中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter之可滾動組件子項緩存KeepAlive實例分析

發布時間:2022-08-08 13:46:21 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

這篇文章主要介紹“Flutter之可滾動組件子項緩存KeepAlive實例分析”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Flutter之可滾動組件子項緩存KeepAlive實例分析”文章能幫助大家解決問題。

首先回想一下,在介紹 ListView 時,有一個addAutomaticKeepAlives 屬性我們并沒有介紹,如果addAutomaticKeepAlives 為 true,則 ListView 會為每一個列表項添加一個 AutomaticKeepAlive 父組件。雖然 PageView 的默認構造函數和 PageView.builder 構造函數中沒有該參數,但它們最終都會生成一個 SliverChildDelegate 來負責列表項的按需加載,而在 SliverChildDelegate 中每當列表項構建完成后,SliverChildDelegate 都會為其添加一個 AutomaticKeepAlive 父組件。下面我們就先介紹一下 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 收到消息后就會開始工作。

Flutter之可滾動組件子項緩存KeepAlive實例分析

現在我們重新運行一下示例,發現每個 Page 頁只會 build 一次,緩存成功了。需要注意,如果我們采用 PageView.custom 構建頁面時沒有給列表項包裝 AutomaticKeepAlive 父組件,則上述方案不能正常工作,因為此時Client 發出消息后,找不到 Server,404 了。

KeepAliveWrapper

雖然我們可以通過 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;
}

關于“Flutter之可滾動組件子項緩存KeepAlive實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丰原市| 双辽市| 南开区| 肥西县| 靖州| 秦安县| 洛隆县| 巴塘县| 三都| 平昌县| 黄冈市| 库伦旗| 武清区| 富平县| 高安市| 东城区| 莱州市| 华池县| 清水河县| 得荣县| 紫云| 高雄县| 交城县| 枝江市| 同德县| 曲沃县| 庄河市| 永城市| 璧山县| 大同市| 承德市| 库伦旗| 怀安县| 房山区| 邯郸县| 高陵县| 道孚县| 光山县| 石柱| 蓝山县| 台东县|