日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Flutter列表滾動定位超強輔助庫使用示例詳解_IOS

作者:LinXunFeng ? 更新時間: 2022-10-05 編程語言

一、痛點

痛點一:Flutter 官方提供了 ScrollController,調用下方兩個方法可以滾動到指定偏移處

void jumpTo(double value)
Future<void> animateTo(
  double offset, {
  required Duration duration,
  required Curve curve,
})

但是官方沒有提供滾動到指定下標位置的功能

痛點二:

為了解決痛點一,業內有很多第三方庫實現了這個功能,其中最知名的莫過于谷歌的 scrollable_positioned_list

而這些庫都有一些相同的問題:

  • 侵入性強,必須使用他們提供的 Widget 來構建列表視圖
  • 不支持 GridView

對此,我決定自己編寫一個庫(flutter_scrollview_observer)來實現這個功能,以及解決以上的問題。

二、優點

  • 侵入性低,不會限制你的列表視圖實現,只要求將列表視圖做為 ViewObserverchild,如果不想用了,直接移除掉 ViewObserver 即可。
  • 基于【不會限制你的列表視圖實現】這一點, flutter_scrollview_observer 支持所有的列表Widget,如:ListViewGridView,甚至 CustomSrollView
  • 防抖動,如果在滾動到指定下標時,列表尾部的可滾動區域已不足以支撐滾動到相應位置,則會自動滾動到最底部,避免回彈的問題

下面正式介紹一下這個庫的使用

三、使用

1、ListView

正常創建和使用 ScrollController 實例

這里你可以使用 ListView 或者 CustomSrollViewSliverList

ScrollController scrollController = ScrollController();
ListView _buildListView() {
  return ListView.separated(
    controller: scrollController,
    ...
  );
}

創建 ListObserverController 實例并將其傳遞給 ListViewObserver

ListObserverController observerController = ListObserverController(controller: scrollController);
ListViewObserver(
  controller: observerController,
  child: _buildListView(),
  ...
)

注意:創建 ListObserverController 實例時需要傳入列表的 ScrollController 實例。 這一步很重要,因為 flutter_scrollview_observer 內部實現原理是基于官方 ScrollController 提供的 jumpToanimateTo 方法

現在即可滾動到指定下標位置了

// 無動畫滾動至下標位置
observerController.jumpTo(index: 100)
// 動畫滾動至下標位置
observerController.animateTo(
  index: 100,
  duration: const Duration(seconds: 1),
  curve: Curves.ease,
);

2、GridView

內容與 ListView 基本一致

正常創建和使用 ScrollController 實例

Widget _buildGridView() {
  return GridView.builder(
    ...
    controller: scrollController,
    ...
  );
}

創建 GridObserverController 實例并將其傳遞給 GridViewObserver

GridObserverController observerController = GridObserverController(controller: scrollController);
GridViewObserver(
  controller: observerController,
  child: _buildGridView(),
)

現在即可滾動到指定下標位置了

observerController.jumpTo(
  index: 40,
);
observerController.animateTo(
  index: 40,
  duration: const Duration(seconds: 1),
  curve: Curves.ease,
);

3、CustomSrollView

支持 SliverListSliverGrid 混合使用的情況!

如上圖所示,CustomSrollViewslivers 中包含有 SliverListSliverGrid

  • 點擊右下角第一個按鈕可滾動到 SliverList 的第 29
  • 點擊第二個按鈕可滾動到 SliverGrid 的第 10 的子部件所在行

正常創建和使用 ScrollController 實例

Widget _buildScrollView() {
  return CustomScrollView(
    controller: scrollController,
    // scrollDirection: Axis.horizontal,
    slivers: [
      _buildSliverListView(),
      _buildSliverGridView(),
    ],
  );
}

正常創建你的 SliverListSliverGrid,并將它們的 BuildContext 記錄起來

Widget _buildSliverListView() {
  return SliverList(
    delegate: SliverChildBuilderDelegate(
      (ctx, index) {
        _sliverListCtx ??= ctx;
        ...
      },
      ...
    ),
  );
}
Widget _buildSliverGridView() {
  return SliverGrid(
    ...
    delegate: SliverChildBuilderDelegate(
      (BuildContext context, int index) {
        _sliverGridCtx ??= context;
        ...
      },
      ...
    ),
  );
}

創建 SliverObserverController 實例并將其傳遞給 SliverViewObserver

注意:在 sliverListContexts 里返回剛才記錄的兩個 SliverBuildContext

SliverObserverController observerController = SliverObserverController(controller: scrollController);
SliverViewObserver(
  controller: observerController,
  child: _buildScrollView(),
  sliverListContexts: () {
    return [
      if (_sliverListCtx != null) _sliverListCtx!,
      if (_sliverGridCtx != null) _sliverGridCtx!,
    ];
  },
  ...
),

現在即可滾動到指定下標位置了

observerController.animateTo(
  sliverContext: _sliverListCtx,
  index: 29,
  duration: const Duration(milliseconds: 300),
  curve: Curves.easeInOut,
);
observerController.animateTo(
  sliverContext: _sliverGridCtx,
  index: 10,
  duration: const Duration(milliseconds: 300),
  curve: Curves.easeInOut,
);

四、說明

1、ViewObserver 的選擇

建議使用相應的 ViewObserver

  • 如果是 ListView 或者純 SliverList,建議使用 ListViewObserver
  • 如果是 GridView 或者純 SliverGrid,建議使用 GridViewObserver
  • 如果是 SliverListSliverGrid,則使用 SliverViewObserver

這樣在 onObserve 回調中拿到數據模型后不用再對其進行類型判斷與轉換。

2、isFixedHeight

子部件為固定高度的情況下,請設置 isFixedHeighttrue,以提升性能!

observerController.jumpTo(
  index: 100, 
  isFixedHeight: true
);
observerController.animateTo(
  index: 100,
  isFixedHeight: true,
  duration: const Duration(seconds: 1),
  curve: Curves.ease,
);

3、sliverContext 是否需要傳

jumpTo({
  required int index,
  BuildContext? sliverContext,
  bool isFixedHeight = false,
})
animateTo({
  required int index,
  required Duration duration,
  required Curve curve,
  BuildContext? sliverContext,
  bool isFixedHeight = false,
})

如上,jumpToanimateTo 方法中都有一個 sliverContext 參數,這是用來指定哪個 sliver 進行滾動操作的。

如果不傳 sliverContext,則默認會是列表中的第一個 sliver,只有你想讓非第一個 sliver 進行滾動的時候才需要傳該值

五、可現實的功能

1、獲得當前視窗中的子部件信息

如上圖控制臺所示,在滾動的過程中可以實時獲取正在顯示的子部件的數據。

2、視頻列表自動播放

這種功能很常見,在列表滾動的時候,指定區域內的被命中的視頻便會自動進行播放。

3、模塊定位

一般詳情頁中都會有的功能,在列表視圖滾動的時候,頂部定位導航視圖跟著更新下標,點擊導航視圖某個下標則會定位到對應的模塊

六、最后

如果這個庫對你很有幫助,請不吝給個 star

GitHub: flutter_scrollview_observer

原文鏈接:https://juejin.cn/post/7129888644290068487

欄目分類
最近更新