Flutter内存更新列表但UI不刷新问题求助
解决Flutter大屏适配中点击分类后UI不刷新的问题
问题出在你更新filteredLists后没有通知Flutter框架状态变更,导致UI不会自动重建。Flutter的StatefulWidget必须通过setState()方法触发UI刷新。
修改方案
在分类项的onTap回调里,更新完filteredLists后调用setState(),让框架重新执行build方法:
onTap: () { filteredLists = Boxes.getFoodItems() .values .where((element) => element.categoryName == foodCategories[index].name) .toList(); print(filteredLists.length); print("object"); // 新增这行代码,通知框架状态更新 setState(() {}); },
额外优化建议
你的代码里存在一些冗余的嵌套和重复监听:
- 外层已经有一个监听FoodCategories的ValueListenableBuilder,内层DrawerHeader里的ValueListenableBuilder可以去掉,直接复用外层的
categories列表即可,避免重复监听和数据转换 - DrawerHeader里嵌套多层ListView可能导致布局问题,建议简化结构
修改后的完整代码示例:
class _OrderCategoryScreenState extends State<OrderCategoryScreen> { List<FoodItem> filteredLists = []; @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Row( children: [ ValueListenableBuilder<Box<FoodCategory>>( valueListenable: Boxes.getFoodCategories().listenable(), builder: (context, box, child) { final categories = box.values.toList().cast<FoodCategory>(); return categories.isEmpty ? Container( color: const Color(0xFFFCF9F9), height: double.infinity, width: MediaQuery.of(context).size.height * 0.30, child: const Center(child: Text("No Categories")), ) : Container( height: double.infinity, width: MediaQuery.of(context).size.height * 0.35, child: Drawer( backgroundColor: const Color(0xFFFCF9F9), elevation: 0, child: ListView( children: [ DrawerHeader( child: ListView.builder( itemCount: categories.length, itemBuilder: (context, index) { return ListTile( tileColor: Colors.green, onTap: () { filteredLists = Boxes.getFoodItems() .values .where((element) => element.categoryName == categories[index].name) .toList(); print(filteredLists.length); print("object"); setState(() {}); }, title: Text(categories[index].name), ); }, ), ), ], ), ), ); }, ), Container( width: MediaQuery.of(context).size.width * 0.5, height: MediaQuery.of(context).size.height * 0.5, color: Colors.amberAccent, child: filteredLists.isEmpty ? const Center(child: Text("Choose A Category")) : ListView.builder( itemCount: filteredLists.length, itemBuilder: (context, index) { return ListTile( title: Text(filteredLists[index].itemName), ); }, ), ), ], ), ), ); } }
原理说明
Flutter采用声明式UI,UI是状态的映射。当你修改filteredLists时,只是改变了内存中的数据,但框架没有感知到这个变化。调用setState()会告诉框架"状态变了,需要重新构建UI",此时build方法会重新执行,右侧的列表就会根据更新后的filteredLists渲染最新内容。
内容的提问来源于stack exchange,提问作者Archit Dandavate
相关产品推荐
相关产品推荐

