第
Flutter之PageView页面缓存与KeepAlive
目录正文构造函数页面缓存KeepAliveKeepAliveWrapper总结
正文
如果要实现页面切换和Tab布局,我们可以使用PageView组件。需要注意,PageView是一个非常重要的组件,因为在移动端开发中很常用,比如大多数App都包含Tab换页效果、图片轮动以及抖音上下滑页切换视频功能等等,这些都可以通过PageView轻松实现。
构造函数
PageView({
Keykey,
this.scrollDirection=Axis.horizontal,//滑动方向
this.reverse=false,
PageControllercontroller,
this.physics,
ListWidgetchildren=constWidget[],
this.onPageChanged,
//每次滑动是否强制切换整个页面,如果为false,则会根据实际的滑动距离显示页面
this.pageSnapping=true,
//主要是配合辅助功能用的,后面解释
this.allowImplicitScrolling=false,
//后面解释
this.padEnds=true,
我们看一个Tab切换的实例,为了突出重点,我们让每个Tab页都只显示一个数字。
//Tab页面
classPageextendsStatefulWidget{
constPage({
Keykey,
requiredthis.text
}):super(key:key);
finalStringtext;
@override
_PageStatecreateState()=_PageState();
class_PageStateextendsStatePage{
@override
Widgetbuild(BuildContextcontext){
print(build${widget.text});
returnCenter(child:Text(${widget.text},textScaleFactor:5));
@override
Widgetbuild(BuildContextcontext){
varchildren=Widget
//生成10个Tab页
for(inti=0;i++i){
children.add(Page(text:$i));
returnPageView(
//scrollDirection:Axis.vertical,//滑动方向为垂直方向
children:children,
如果将PageView的滑动方向指定为垂直方向(上面代码中注释部分),则会变为上下滑动切换页面。
页面缓存
我们在运行上面示例时,可能已经发现:每当页面切换时都会触发新Page页的build,比如我们从第一页滑到第二页,然后再滑回第一页时,控制台打印如下:
flutter:build0
flutter:build1
flutter:build0
可见PageView默认并没有缓存功能,一旦页面滑出屏幕它就会被销毁,和ListView/GridView不一样,在创建ListView/GridView时我们可以手动指定ViewPort之外多大范围内的组件需要预渲染和缓存(通过cacheExtent指定),只有当组件滑出屏幕后又滑出预渲染区域,组件才会被销毁,但是不幸的是PageView并没有cacheExtent参数!但是在真实的业务场景中,对页面进行缓存是很常见的一个需求,比如一个新闻App,下面有很多频道页,如果不支持页面缓存,则一旦滑到新的频道旧的频道页就会销毁,滑回去时又得重新请求数据和构建页面,这样极度消耗性能。
按道理cacheExtent是Viewport的一个配置属性,且PageView也是要构建Viewport的,那么为什么就不能透传一下这个参数呢?于是笔者带着这个疑问看了一下PageView的源码,发现在PageView创建Viewport的代码中是这样的:
child:Scrollable(