Flutter Listview 缓存item滑动后不进行重新渲染
使用KeepAliveWrapper包裹:
KeepAliveWrapper源码:
class KeepAliveWrapper extends StatefulWidget {const KeepAliveWrapper({Key? key, @required this.child, this.keepAlive = true}): super(key: key);final Widget? child;final bool keepAlive;@overrideState<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}class _KeepAliveWrapperState extends State<KeepAliveWrapper>with AutomaticKeepAliveClientMixin {@overrideWidget build(BuildContext context) {return widget.child!;}@overridebool get wantKeepAlive => widget.keepAlive;@overridevoid didUpdateWidget(covariant KeepAliveWrapper oldWidget) {if (oldWidget.keepAlive != widget.keepAlive) {// keepAlive 状态需要更新,实现在 AutomaticKeepAliveClientMixin 中updateKeepAlive();}super.didUpdateWidget(oldWidget);}
}
使用示例:
@override
Widget build(BuildContext context) {var children = <Widget>[];for (int i = 0; i < 6; ++i) {//只需要用 KeepAliveWrapper 包装一下即可children.add(KeepAliveWrapper(child:Page( text: '$i'));}return PageView(children: children);
}
测试下:
class KeepAliveDemo extends StatelessWidget {const KeepAliveDemo({Key? key,}) : super(key: key);@overrideWidget build(BuildContext context) {return PageView.builder(itemCount: 5,itemBuilder: (BuildContext ctx, int index) {return KeepAliveWrapper(child: PageItem(text: "$index"),keepAlive: true,);},);}
}class PageItem extends StatelessWidget {PageItem({this.text});final String? text;@overrideWidget build(BuildContext context) {print("flutter build ${text}");return Center(child: Text(text!, textScaleFactor: 5.0));}
}
运行发现,keepAlive为true时每个Item都缓存了,为false时,每个Item都会重新创建,OK。
转自:【致程序猿】Flutter 之 可滚动组件子项缓存 KeepAlive_keepalivewrapper-CSDN博客