Flutter问题:滚动时ListView组件状态重置如何解决?
解决Flutter ListView滚动时子组件状态重置的问题
你当前的问题出在把AutomaticKeepAliveClientMixin用在了承载ListView的页面State类上,而不是ListView内部需要保留状态的子组件State类上。ListView滚动时销毁复用的是内部的子组件,所以保活逻辑要加在子组件层面。
正确实现步骤
- 封装需要保活的子组件
把需要保留状态的子组件单独抽成StatefulWidget,并在它的State类中混入AutomaticKeepAliveClientMixin:
class KeepAliveItem extends StatefulWidget { const KeepAliveItem({Key? key}) : super(key: key); @override State<KeepAliveItem> createState() => _KeepAliveItemState(); } class _KeepAliveItemState extends State<KeepAliveItem> with AutomaticKeepAliveClientMixin { // 需要保留的状态数据 Duration _dateClockInitial = Duration.zero; // 模拟状态更新操作 void _addDuration() { setState(() { _dateClockInitial += const Duration(seconds: 1); }); } @override Widget build(BuildContext context) { super.build(context); // 必须调用super.build,否则保活不生效 return GestureDetector( onTap: _addDuration, child: Container( height: 100, margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), color: Colors.grey[200], child: Center(child: Text('累计时长:${_dateClockInitial.inSeconds}秒')), ), ); } @override bool get wantKeepAlive => true; // 返回true开启状态保活 }
- 在ListView中使用该组件
原页面的ListView直接使用封装好的保活子组件即可:
class MyClass extends StatefulWidget { const MyClass({Key? key}) : super(key: key); @override State<MyClass> createState() => _MyClassState(); } class _MyClassState extends State<MyClass> { @override Widget build(BuildContext context) { return ListView.builder( itemCount: 20, itemBuilder: (context, index) { return const KeepAliveItem(); }, ); } }
关键注意事项
- 若使用普通
ListView(非builder),同样要确保每个需要保活的子组件是独立的StatefulWidget并配置Mixin。 - 子组件的
build方法必须调用super.build(context),这是保活生效的必要条件。 - 如果子组件有多层嵌套,保活逻辑要加在最内层持有状态的组件上。
内容的提问来源于stack exchange,提问作者Preem Palver2
相关产品推荐
相关产品推荐

