首页 > 解决方案 > Flutter:提供者:ListView 在 notifyListener() 之后没有重新绘制

问题描述

我已经看到这个问题被问了很多次,没有答案。我想深入了解它。如果没有这个工作,我真的无法在我的应用程序中前进......

为什么 Provider 在 notifyListeners 调用后无法触发 ListView 重绘。

简化代码示例(数据桶):

class TheData extends ChangeNotifier {
   List<ListTile> data = [
      ListTile(title: Text('A')),
   ];

   addTile() {
      data.add(ListTile(title: Text('B')));
      notifyListeners();
   }
}

使用 TheData 的屏幕:

class TheScreen extends StatefulWidget {
  @override
  TheScreenState createState() => TheScreenState();
}

class TheScreenState extends State<TheScreen> {
  @override
  Widget build(BuildContext context) {
    return Consumer<TheData>(
       builder: (ctx, _theData, _) {
           print('rebuilding count = ${_theData.data.length}');
           return ListView(
              children: _theData.data,
           );
       }
    );
  }
}

假设 TheData 类在小部件树中的此屏幕上方正确提供,并且我触发了“addTile()”。打印显示“数据”中现在有 2 个元素,但 ListView 没有改变。

这真让我抓狂。

标签: flutterflutter-provider

解决方案


我不知道为什么这会产生影响,或者它是否效率较低......但是,使用 ListView.builder() 可以解决问题:

class TheScreen extends StatefulWidget {
  @override
  TheScreenState createState() => TheScreenState();
}

class TheScreenState extends State<TheScreen> {
  @override
  Widget build(BuildContext context) {
    return Consumer<TheData>(
       builder: (ctx, _theData, _) {
           print('rebuilding count = ${_theData.data.length}');
           return ListView.builder(
              itemCount: _theData,data.length,
              itemBuilder: (c, i) => _theData.data[i],
           );
       }
    );
  }
}

推荐阅读