AutomaticKeepAliveClientMixin 缓存PageView页面

发布时间 2024-01-05 00:24:22作者: 鲤斌
一旦页面滑出屏幕它就会被销毁 ,实际项目开发中对页面进行缓存是很常见的一个需求,下面我们就看看如何使用AutomaticKeepAliveClientMixin 缓存页面。
注意:使用时一定要注意是否必要,因为对所有列表项都缓存的会导致更多的内存消耗。
class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PageView.builder(
      itemCount: 5,
      scrollDirection: Axis.vertical, // 滑动方向为垂直方向
      itemBuilder: (BuildContext context, int index) {
        return Page(
          index: index,
        );
      },
    ));
  }
}

class Page extends StatefulWidget {
  final int index;
  const Page({super.key, required this.index});

  @override
  State<Page> createState() => _PageState();
}

class _PageState extends State<Page> with AutomaticKeepAliveClientMixin {
  //缓存加with AutomaticKeepAliveClientMixin
  @override
  Widget build(BuildContext context) {
    print("验证是否加缓存");
    return Center(
      child: Text("第${widget.index}"),
    );
  }

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true; //返回true就缓存页面
}

自定义KeepAliveWrapper 缓存页面

AutomaticKeepAliveClientMixin 可以快速的实现页面缓存功能,但是通过混入的方式实现不是很优雅, 所以我们有必要对AutomaticKeepAliveClientMixin 混入进行封装
import 'package:flutter/material.dart';

class KeepAliveWrapper extends StatefulWidget {
  const KeepAliveWrapper({
    Key? key,
    @required this.child,
    this.keepAlive = true,
  }) : super(key: key);

  final Widget? child;
  final bool keepAlive;

  @override
  State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}

class _KeepAliveWrapperState extends State<KeepAliveWrapper>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    // 返回子组件
    return widget.child!;
  }

  @override
  bool get wantKeepAlive => widget.keepAlive;

  @override
  void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
    super.didUpdateWidget(oldWidget);

    // 如果 `keepAlive` 属性发生变化,则更新 `wantKeepAlive` 值
    if (oldWidget.keepAlive != widget.keepAlive) {
      // 通知 Flutter 更新 `wantKeepAlive` 的值
      updateKeepAlive();
    }
  }
}

//这里使用covariant协变关键字,感兴趣可以研究一下dart covariant
使用
        return KeepAliveWrapper( //页面比较多会耗内存
          child: Page(
            index: index,
          ),
        );