如何在Flutter中滚动时保持状态?

5
我有一个简单的网格,它比屏幕实际空间更大,可以向上和向下滚动。
每个单元格都有一个 onTap() 方法来更改单元格颜色。
问题在于,一旦我将更改后的单元格滚出视图,状态就不会保持。
有什么想法吗? enter image description here
class GridWidget extends StatefulWidget {
  @override
  _GridWidgetState createState() => new _GridWidgetState();
}

class _GridWidgetState extends State<GridWidget> {
  @override
  Widget build(BuildContext context) {
    Color cellColor = Colors.white;

    return new GridView.count(
      crossAxisCount: 10,
      children: new List.generate(100, (index) {
        return new CellWidget(
          index: index,
          color: cellColor,
          text: new Text(index.toString()),
        );
      }),
    );
  }
}

CellWidget
单元格窗口小部件
...
class _CellWidgetState extends State<CellWidget> {
  Color cellColor = Colors.white;
  Text cellText = new Text('white');

  @override
  void initState() {
    super.initState();
    cellColor = widget.color;
    cellText = widget.text;
  }

  _changeCell(index) {
    setState(() {
      cellColor = Colors.lightBlue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: () => _changeCell(widget.index),
      child: new Container(
        width: double.infinity,
        height: double.infinity,
        child: new Center(child: cellText),
      ),
    );
  }
}

搜索 PageState(抱歉只能在手机上) - Günter Zöchbauer
你不能管理一个集合吗?ontop只是将索引值添加到该集合中? - user1462442
不太确定如何 - Patrioticcow
你可以在CellWidget上添加一个onTap监听器。这样,你就可以跟踪GridWidget中被点击的项目。color: cellColor应该依赖于该点击。 - Rene
2个回答

9
您可以使用AutomaticKeepAliveClientMixin类来防止您的项在滚动时被处理。 更改CellWidget中的代码应该解决您的问题:
class _CellWidgetState extends State<CellWidget> with AutomaticKeepAliveClientMixin {
  Color cellColor = Colors.white;
  Text cellText = new Text('white');

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    cellColor = widget.color;
    cellText = widget.text;
  }

  _changeCell(index) {
    setState(() {
      cellColor = Colors.lightBlue;
    });
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return new GestureDetector(
      onTap: () => _changeCell(widget.index),
      child: new Container(
        width: double.infinity,
        height: double.infinity,
        child: new Center(child: cellText),
      ),
    );
  }
}

这是相关技术的文档链接: AutomaticKeepAliveClientMixin

0
在Flutter文档中,ListView.builder提到当您滚动时,ListView的子项将按需构建...我认为GridView.count也是同样的情况。

应该有一种方法来禁用那种行为。 - Patrioticcow
使用 GridView 构造函数?https://docs.flutter.io/flutter/widgets/GridView/GridView.html - Amir Hossein Qasemi Moqaddam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接