Flutter GridView의 다중 선택으로 모든 것을 다시 그리지 않는 방법

10539 단어 Flutter
Flutter의 GridView를 사용하여 정사각형 썸네일을 표시하는 앱을 만들고 있습니다. 여러 개를 선택할 수는 있지만 탭할 때마다 모두 다시 그려져 화면이 깜박입니다.
문제를 해결할 수 있었으므로 소개합니다.



소스 코드



multi_select_gridview.dart
import 'package:flutter/material.dart';

class MultiSelectScreen extends StatefulWidget {
  @override
  _MultiSelectState createState() => _MultiSelectState();
}

class _MultiSelectState extends State<MultiSelectScreen> {
  List<String> list = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T'];
  List<bool> selectList = new List.filled(20, false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GridView.extent(
        maxCrossAxisExtent: 150,
        children: List.generate(20, (index) {    
          return MultiSelectItem(
            name: list[index],
            selectList: selectList,
            index:index);   
      })),
    );}
}

/// isSelected で再描画を行い、selectList を親に参照させることで、
/// すべてが再描画されることを防ぎます。
class MultiSelectItem extends StatefulWidget {
  MultiSelectItem({
    @required this.name,
    @required this.selectList,
    @required this.index,
    });
  String name;
  List<bool> selectList;
  int index;
  bool isSelected = false;
  @override
  _MultiSelectItemState createState() => _MultiSelectItemState();
}

class _MultiSelectItemState extends State<MultiSelectItem> {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(2),         
      child: GestureDetector(
        onTap: () {
          setState((){ 
            widget.isSelected = !widget.isSelected;
            widget.selectList[widget.index] = widget.isSelected;
            });
        },
        child: Stack(children: <Widget>[
          Container(color: Colors.grey),
          Center(child: Text(widget.name, style: TextStyle(fontSize: 30,))), 
          Positioned(
            right: 6.0, bottom: 6.0,
            child: CircleAvatar( 
              backgroundColor: widget.isSelected ? Colors.black38 : Color(0x00000000),
              child: Icon( widget.isSelected ? Icons.check : null, 
              size: 36,
              color: Colors.lightBlue
            ))),
          ]),
      ),);}
}

해설



복수 선택하기 위해서 List< bool> 를 사용해 setState() 를 실행합니다. 그러면 GridView 전체가 다시 그려져 화면이 깜박이게 됩니다.
따라서 GridView의 개별 항목을 StatefulWidget으로 만듭니다. 아이템에는, 자신의 isSelected 와 부모를 참조하는 selectList 의 2 개를 갖게 하는 것이 포인트입니다. 탭하면 자신의 isSelected 만 다시 그려집니다. selectList도 변경하지만 다시 그리기에는 영향을주지 않습니다.

요약



GlidView에서 선택할 때마다 화면이 모두 다시 그려지는 문제의 해결 방법을 소개했습니다. Flutter 초보자입니다. 이 솔루션을 조사하기 위해 몇 가지 샘플을 시도했습니다. setState() 에 대해서나, StatefulWidget 와 StatelessWidget 의 차이 등, 갑자기 돌아서서 꽤 공부가 되었습니다.

좋은 웹페이지 즐겨찾기