如何提升包含DropDownButton的短ListView的构建速度?
性能根因
Flutter官方DropdownButton会在控件首次构建时一次性生成所有传入的DropdownMenuItem实例并完成预布局,哪怕下拉框没有展开也会执行这部分逻辑,和原生Android Spinner的懒加载逻辑完全不同。你的场景下10个下拉框累计要预构建10000个item,这才是卡顿的核心来源,和ListView本身的构建性能无关。
优化方案
方案1:替换懒加载下拉组件
放弃官方DropdownButton,改用支持下拉展开时才动态加载item的第三方下拉组件,仅在用户点击展开下拉框时用ListView.builder构建可见范围内的item,1000条数据的渲染耗时可以压缩到几乎不可感知。方案2:延后下拉item的注入时机
继续使用官方DropdownButton时,不要提前传入全量selections列表:- 初始化时给
DropdownButton的items属性传入空数组,仅保留选中值的展示 - 监听下拉框的点击事件,用户点击展开前再把全量
selections赋值给items触发下拉面板构建
可以避免列表构建时的10倍item预构建开销,列表加载速度提升10倍以上。
- 初始化时给
方案3:增加加载态避免UI冻结感知
如果优化后仍有可感知的构建耗时,可以拆分构建任务增加加载过渡:// 增加loading状态 bool isLoading = false; // 修改按钮点击逻辑 onPressed: () async { if(!showList){ setState(()=> isLoading = true); // 让出当前帧先渲染进度条 await Future.delayed(Duration.zero); } setState((){ showList = !showList; isLoading = false; }); } // 页面展示部分替换 Expanded( child: isLoading ? const Center(child: CircularProgressIndicator()) : showList ? // 你的原有ListView逻辑 : const Text("List Not Built"), )方案4:缓存静态控件实例
你当前的selections列表已经是全局缓存的状态,可以进一步把每个列表项的DropdownButton实例提前缓存,ListView构建时直接复用缓存实例,不需要每次重建都重新实例化控件。
内容的提问来源于stack exchange,提问作者Mena
相关产品推荐
相关产品推荐

