You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:35:18