<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文為大家分析了Flutter之可捲動元件子項快取 KeepAlive,供大家參考,具體內容如下
首先回想一下,在介紹 ListView 時,有一個addAutomaticKeepAlives 屬性我們並沒有介紹,如果addAutomaticKeepAlives 為 true,則 ListView 會為每一個列表項新增一個 AutomaticKeepAlive 父元件。雖然 PageView 的預設建構函式和 PageView.builder 建構函式中沒有該引數,但它們最終都會生成一個 SliverChildDelegate 來負責列表項的按需載入,而在 SliverChildDelegate 中每當列表項構建完成後,SliverChildDelegate 都會為其新增一個 AutomaticKeepAlive 父元件。下面我們就先介紹一下 AutomaticKeepAlive 元件。
AutomaticKeepAlive 的元件的主要作用是將列表項的根 RenderObject 的 keepAlive 按需自動標記 為 true 或 false。為了方便敘述,我們可以認為根 RenderObject 對應的元件就是列表項的根 Widget,代表整個列表項元件,同時我們將列表元件的 Viewport區域 + cacheExtent(預渲染區域)稱為載入區域 :
1.當 keepAlive 標記為 false 時,如果列表項滑出載入區域時,列表元件將會被銷燬。
2.當 keepAlive 標記為 true 時,當列表項滑出載入區域後,Viewport 會將列表元件快取起來;當列表項進入載入區域時,Viewport 從先從快取中查詢是否已經快取,如果有則直接複用,如果沒有則重新建立列表項。
那麼 AutomaticKeepAlive 什麼時候會將列表項的 keepAlive 標記為 true 或 false 呢?答案是開發者說了算!Flutter 中實現了一套類似 C/S 的機制,AutomaticKeepAlive 就類似一個 Server,它的子元件可以是 Client,這樣子元件想改變是否需要快取的狀態時就向 AutomaticKeepAlive 發一個通知訊息(KeepAliveNotification),AutomaticKeepAlive 收到訊息後會去更改 keepAlive 的狀態,如果有必要同時做一些資源清理的工作(比如 keepAlive 從 true 變為 false 時,要釋放快取)。
我們基於上一節 PageView 範例,實現頁面快取,根據上面的描述實現思路就很簡單了:讓Page 頁變成一個 AutomaticKeepAlive Client 即可。為了便於開發者實現,Flutter 提供了一個 AutomaticKeepAliveClientMixin ,我們只需要讓 PageState 混入這個 mixin,且同時新增一些必要操作即可:
class _PageState extends State<Page> with AutomaticKeepAliveClientMixin { @override Widget build(BuildContext context) { super.build(context); // 必須呼叫 return Center(child: Text("${widget.text}", textScaleFactor: 5)); } @override bool get wantKeepAlive => true; // 是否需要快取 }
程式碼很簡單,我們只需要提供一個 wantKeepAlive,它會表示 AutomaticKeepAlive 是否需要快取當前列表項;另外我們必須在 build 方法中呼叫一下 super.build(context),該方法實現在 AutomaticKeepAliveClientMixin 中,功能就是根據當前 wantKeepAlive 的值給 AutomaticKeepAlive 傳送訊息,AutomaticKeepAlive 收到訊息後就會開始工作。
現在我們重新執行一下範例,發現每個 Page 頁只會 build 一次,快取成功了。需要注意,如果我們採用 PageView.custom 構建頁面時沒有給列表項包裝 AutomaticKeepAlive 父元件,則上述方案不能正常工作,因為此時Client 發出訊息後,找不到 Server,404 了。
雖然我們可以通過 AutomaticKeepAliveClientMixin 快速的實現頁面快取功能,但是通過混入的方式實現不是很優雅,因為必須更改 Page 的程式碼,有侵入性,這就導致不是很靈活,比如一個元件能同時在列表中和列表外使用,為了在列表中快取它,則我們必須實現兩份。為了解決這個問題,筆者封裝了一個 KeepAliveWrapper 元件,如果哪個列表項需要快取,只需要使用 KeepAliveWrapper 包裹一下它即可。
@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); }
下面是 KeepAliveWrapper 的實現原始碼:
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; }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45