Flutter 在 ListView 中仅重建一行

Posted

技术标签:

【中文标题】Flutter 在 ListView 中仅重建一行【英文标题】:Flutter Rebuild Just One Row in ListView 【发布时间】:2019-07-11 05:54:50 【问题描述】:

我的应用中有一个列表视图。每行都有一些仅影响同一行的按钮。我不想刷新整个Listview。当我在点击按钮时调用setState() 时,会导致整个Listview 刷新。

如何在行内的同一行点击按钮上刷新?

在我的代码中,点击按钮必须导致相同按钮的颜色发生变化:

....
....
....

List<mPlay> playList = new List();

....
....
....

@override
  Widget build(BuildContext context) 
    return new Directionality(
        textDirection: globals.textDirection,
        child: new Scaffold(
            key: globalKey,
            body: (playList != null && playList.length > 0)
                ? new SmartRefresher(
                    headerBuilder: _buildHeader,
                    enablePullDown: true,
                    enablePullUp: true,
                    onRefresh: _onRefresh,
                    onOffsetChange: _onOffsetCallback,
                    child: new ListView.builder(
                      padding: const EdgeInsets.all(0),
                      itemCount: playList.length,
                      itemBuilder: (context, i) 
                        return _buildRow(playList[i], i);
                      ,
                    ))
                : EmptyWidget()));
  

  Widget _buildRow(mPlay play, int index) 
  return new Card(
        child: new Container(
        child: new Row(children: <Widget>[
        new InkWell(
                            child: new IconButton(
                                icon: Icon(
                                  Icons.group_add,
                                  color: play.isContributed == "1"
                                      ? Colors.blueAccent
                                      : Colors.black,
                                ),                                
                                onPressed: () 
                                  play.isContributed =
                                      play.isContributed == "0" ? "1" : "0";
                                  setState(() 
                                    playList[index].isContributed =
                                        play.isContributed;
                                  );
                                ))
        ])
        ))


  

【问题讨论】:

【参考方案1】:

您必须使用范围模型、BLoC、redux 等状态管理方法。 Checkout this post to get a proper idea

【讨论】:

你能提供一些示例代码吗?这将提高您的答案的长期实用性,并帮助更多的人。【参考方案2】:

我遇到了同样的问题。我按照以下步骤进行了计算:

    创建一个流控制器 判断并将 streamController 分配给稍后将刷新的行 调用 streamController.add(...) 刷新行。

下面是示例代码:

在列表视图构建器中

        return ListView.builder(
                    itemCount: 100,
                    itemBuilder: (BuildContext context, int index) 
                        return CMyListViewRow(index == _iSelectedRowIndex ? _streamCtlBet : null);
                    );

在 CMyListViewRow 中,您可以执行以下操作:

       if( _streamController != null )
            return StreamBuilder(
                initialData: 0,
                stream: _streamController.stream,
                builder: (BuildContext context, AsyncSnapshot<int> snapshot) 
                    return _getRow();
                );
        
        else
            return _getRow();
        

【讨论】:

以上是关于Flutter 在 ListView 中仅重建一行的主要内容,如果未能解决你的问题,请参考以下文章

Flutter setState 重建整页功能

Flutter - 在列表视图中仅选择单个项目

flutter listview item滚出屏幕不重置状态

在 Flutter 中使用 InheritedWidget 时 ListView 失去滚动位置

Flutter Provider-重建列表项而不是列表视图

Flutter Listview.Separated 在列表的开头和结尾添加分隔符