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

Flutter长列表滚动时ExpansionTile自动收起问题如何解决?

问题原因
  • ExpansionTile默认内部自行维护展开状态,当ListView滚动时,超出视口范围的组件会被Flutter系统回收重建,重建后的ExpansionTile会恢复到默认的收起状态,导致之前的展开状态丢失。
  • 你添加的AutomaticKeepAliveClientMixin是用于PageView/TabBarView的子页面整体保活,无法作用于ListView内部的单个子组件,所以无法解决该问题。
修复步骤
  1. 首先在MyAppState中新增状态列表,存储每一天对应ExpansionTile的展开状态:
// 下标0对应周一,1对应周二,以此类推到5对应周六
List<bool> _expansionStatus = List.filled(6, false);
  1. 给每一个ExpansionTile添加initiallyExpanded和onExpansionChanged参数,绑定外部维护的状态:
    以周一的ExpansionTile为例,修改后代码如下:
Theme(
  data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
  child: ExpansionTile(
    initiallyExpanded: _expansionStatus[0], // 绑定对应下标的展开状态
    onExpansionChanged: (value) {
      setState(() {
        _expansionStatus[0] = value;
      });
    },
    title: const Text(
      'Monday',
      style: TextStyle(fontWeight: FontWeight.bold),
    ),
    children: _getChildren(4, arrMondayOutlet),
  ),
),

剩余周二到周六的ExpansionTile依次把下标改为1~5即可。
3. 冗余代码清理:你在main函数里已经套了一层MaterialApp,build方法里又返回了一次MaterialApp,属于重复嵌套,直接把build里的外层MaterialApp去掉,直接返回Scaffold即可,避免出现主题、路由配置冲突的问题。

可选优化建议
  • Days类的属性建议明确指定类型,不要用var声明,可以避免后续开发中的类型安全问题。
  • 可以把周一到周六的数据源、标题封装成一个统一的列表,用循环生成ExpansionTile,减少重复代码量。

内容的提问来源于stack exchange,提问作者Kuldeep

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:48:03