Flutter Provider中Consumer移除列表项后UI不更新问题求助
问题描述
点击蓝色添加按钮3次后,myList中成功添加了3个元素,终端打印也显示列表长度为3。但长按第三个卡片尝试删除时,虽然终端打印显示元素已被移除,UI却没有同步更新列表。再次长按原本第三个位置的卡片时,直接抛出范围异常:
========= Exception caught by gesture ===============================================================
The following RangeError was thrown while handling a gesture:
RangeError (index): Invalid value: Not in inclusive range 0..1: 2

完整代码
controller.dart
import 'package:flutter/cupertino.dart'; class MyController extends ChangeNotifier{ var myList = []; void addItemsInList(){ myList.add('item#${myList.length} '); //todo: 1* forgot notifyListeners(); } void removeItems(index){ myList.removeAt(index) ; } }
view.dart
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:provider_4/controller/controller_file.dart'; class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Consumer<MyController>( builder: (context, snapshot, child) { return Scaffold( floatingActionButton: FloatingActionButton( onPressed: (){ Provider . of <MyController> (context, listen: false) . addItemsInList(); print('myList.length gives: ${snapshot.myList.length}'); print(snapshot.myList); }, child: Icon(Icons.add), ), body: ListView.builder( itemCount: snapshot.myList.length , // replace with something like myList.length itemBuilder: (context, index) => Card( child: ListTile( onLongPress: () { Provider . of <MyController> (context, listen: false).removeItems(index); // snapshot.myList.removeAt(index); print(snapshot.myList); }, title: Text( 'Title', // replace with something like myList[index].title style: TextStyle( fontSize: 20, color: Colors.black87, fontWeight: FontWeight.bold, ), ), subtitle: Text( 'Details of title above', // replace with something like myList[index].details style: TextStyle( fontSize: 20, color: Colors.deepPurple, fontWeight: FontWeight.bold, ), ), trailing: Icon(Icons.check_circle, color: Colors.green,), ), ), ), ); } ), ); } }
解决方案
修复UI不更新问题
核心问题是removeItems方法删除元素后没有调用notifyListeners(),导致Provider无法感知数据变化,无法通知UI重建。修改controller.dart中的方法:void removeItems(index){ myList.removeAt(index); notifyListeners(); // 新增这行,通知UI更新数据 }解决打印旧数据的问题
点击添加按钮后直接打印snapshot.myList会拿到旧数据,因为notifyListeners()是异步触发UI重建的。把打印逻辑移到controller的addItemsInList方法里,就能打印最新数据:void addItemsInList(){ myList.add('item#${myList.length} '); print('myList.length gives: ${myList.length}'); print(myList); notifyListeners(); }同时删除view中按钮点击事件里的打印代码即可。
优化列表内容绑定(可选)
当前列表的标题和副标题是固定文本,建议绑定myList中的数据,让内容和数据对应:title: Text( snapshot.myList[index], // 使用列表中的动态数据 style: TextStyle( fontSize: 20, color: Colors.black87, fontWeight: FontWeight.bold, ), ),
内容的提问来源于stack exchange,提问作者Saad Mansoor
相关产品推荐
相关产品推荐

