Flutter中ListView添加新数据后无法更新显示问题求助
问题根因
90%概率是Provider实例作用域问题,两个页面访问的不是同一个mockData对象,导致新增数据只存在输入页的mockData实例里,首页实例没有更新。小概率是状态监听配置不对,没有触发页面重建。
修复步骤
- 调整Provider注册位置
把mockData的Provider注册移到MaterialApp外层,保证全局所有路由页面共享同一个实例,示例代码:
void main() { runApp( ChangeNotifierProvider( create: (context) => mockData(), child: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( // 原有路由、主题等配置保持不变 ); } }
- 优化首页状态监听写法
用Consumer包裹需要更新的列表区域,既可以避免全页面不必要重建,也能保证监听生效,修改feedScreen的body部分代码:
body: SingleChildScrollView( child: Column( children: [ menuButtons(), Consumer<mockData>( builder: (context, mockDataInstance, child) { var posts = mockDataInstance.items; if (filter != 0) { posts = posts.where((i) => i.tag == filter).toList(); } return Container( padding: const EdgeInsets.all(8), child: ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: posts.length, itemBuilder: (ctx, i) => postWidget(post: posts[i]), ), ); }, ), ], ), ),
原来写在build方法开头的posts获取代码可以直接删除。
- 修正输入页控制器销毁顺序
把submitted方法里的控制器销毁操作移到最后,避免提前销毁控件引发未知异常:
void submitted() { String titleCheck = titleController.text; String bodyCheck = bodyController.text; int tag = Tag.indexOf(_chosenValue); if (titleCheck.isEmpty || bodyCheck.length < 10) { return; } final newPost = dataFeed( imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d", name: "Priyam ", title: titleCheck, text: bodyCheck, tag: tag, ); Provider.of<mockData>(context, listen: false).addPost(newPost); Navigator.of(context).pop(); // 销毁操作移到最后 titleController.dispose(); bodyController.dispose(); }
- 可选规范优化
Dart官方要求类名使用大驼峰命名,你当前的mockData、feedScreen、dataFeed都是小驼峰,虽然不会直接引发运行错误,但很容易出现类型匹配、导包错误,建议统一改成大驼峰:MockData、FeedScreen、DataFeed。
另外dataFeed类不需要with ChangeNotifier,它只是纯数据模型,不需要发送状态通知,直接删掉就行。
验证方法
如果改完还不生效,在mockData的构造方法里加一行打印print("MockData实例创建");,运行App看控制台输出次数,如果超过1次,就是存在多个实例,重新调整Provider注册位置即可。
内容的提问来源于stack exchange,提问作者Prem
相关产品推荐
相关产品推荐

