1 在使用PageView的时候 我可以发现,直接使用没有缓存的功能,通常是滑动到当前页就加载当前页,划走后就立马销毁
2 子Flutter中 提供了一个 AutomaticKeepAliveClientMixin ,我们只需要让 PageState 混入这个 mixin,且同时添加一些必要操作即可实现缓存的功能
class ItemContainerState extends State<MyItemContainerState> with AutomaticKeepAliveClientMixin{
混入后有几个关键点,需要处理一下
1 super.build(context);
@override
Widget build(BuildContext context) {
super.build(context);
2
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
class MyViewPagerState extends StatefulWidget {
const MyViewPagerState({Key? key}) : super(key: key);
@override
State<MyViewPagerState> createState() => _MyState();
}
class _MyState extends State<MyViewPagerState> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("MyViewPagerState"),
),
body: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: double.infinity),
child: PageView(
scrollDirection:Axis.vertical,
allowImplicitScrolling: true,
children: <Widget>[
MyItemContainerState(colors: Colors.yellow,pageName: "yellow",),
MyItemContainerState(colors: Colors.red,pageName: "red",),
MyItemContainerState(colors: Colors.green,pageName: "green",),
MyItemContainerState(colors: Colors.blue,pageName: "blue",),
MyItemContainerState(colors: Colors.deepPurple,pageName: "deepPurple",)
],
)
),
);
}
}
class MyItemContainerState extends StatefulWidget {
const MyItemContainerState({Key? key,required this.colors,required this.pageName}) : super(key: key);
final MaterialColor colors ;
final String pageName ;
@override
State<MyItemContainerState> createState() {
// TODO: implement createState
return ItemContainerState(colors,pageName);
}
}
class ItemContainerState extends State<MyItemContainerState> with AutomaticKeepAliveClientMixin{
MaterialColor colors ;
String pageName ;
ItemContainerState(this.colors,this.pageName);
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
print("创建$pageName");
// TODO: implement build
return Container(
width: double.infinity,
height: double.infinity,
color: colors,
alignment: Alignment.center,
child: Text(pageName,style: TextStyle(fontSize: 50,color: Colors.white),),
);
}
@override
void dispose() {
// TODO: implement dispose
print("销毁$pageName");
super.dispose();
}
}
1 运行应用 执行yellow 页面和 red页面
2 运行应用 执行green
3 创建 green页面 且没有销毁任何页面
4 创建完5个页面有 没有再次创建,也没有销毁任何页面
封装,保存代码
@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 KeepAliveWrapper extends StatefulWidget {
const KeepAliveWrapper({
Key? key,
this.keepAlive = true,
required this.child,
}) : super(key: key);
final bool keepAlive;
final Widget child;
@override
_KeepAliveWrapperState createState() => _KeepAliveWrapperState();
}
class _KeepAliveWrapperState extends State<KeepAliveWrapper>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context);
return widget.child;
}
@override
void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
if(oldWidget.keepAlive != widget.keepAlive) {
// keepAlive 状态需要更新,实现在 AutomaticKeepAliveClientMixin 中
updateKeepAlive();
}
super.didUpdateWidget(oldWidget);
}
@override
bool get wantKeepAlive => widget.keepAlive;
}
class KeepAliveTest extends StatelessWidget {
const KeepAliveTest({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (_, index) {
return KeepAliveWrapper(
// 为 true 后会缓存所有的列表项,列表项将不会销毁。
// 为 false 时,列表项滑出预加载区域后将会别销毁。
// 使用时一定要注意是否必要,因为对所有列表项都缓存的会导致更多的内存消耗
keepAlive: true,
child: ListItem(index: index),
);
});
}
}
class ListItem extends StatefulWidget {
const ListItem({Key? key, required this.index}) : super(key: key);
final int index;
_ListItemState createState() => _ListItemState();
}
class _ListItemState extends State<ListItem> {
Widget build(BuildContext context) {
return ListTile(title: Text('${widget.index}'));
}
void dispose() {
print('dispose ${widget.index}');
super.dispose();
}
}