Flutter學習之重新整理元件-pull_to_refresh
highlight: androidstudio
持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第30天,點選檢視活動詳情
- 本文主要介紹三方元件中重新整理元件,下拉重新整理,上拉載入更多。
1. 重新整理元件
對於重新整理元件一些經過時間的考驗,基本上都解決了問題,類似我們MJRefresh
,使用的人比較多
比如:pull_to_refresh: ^2.0.0
或者 flutter_easyrefresh: ^2.2.1
基本上都是可以解決我們的需求,自定義上拉下拉動畫,文字描述等。這裡我使用的是pull_to_refresh
,這裡作者適配了flutter 3.0 適配
我們依賴的時候新增git地址
dart
pull_to_refresh:
git:
url: https://github.com/miquelbeltran/flutter_pulltorefresh
2. pull_to_refresh
這裡介紹下pull_to_refresh
的使用。元件的特性如下:
- 提供上拉載入和下拉重新整理
- 幾乎適合所有部件
- 提供全域性設定預設指示器和屬性
- 提供多種比較常用的指示器
- 支援Android和iOS預設滑動引擎,可限制越界距離,打造自定義彈性動畫,速度,阻尼等。
- 支援水平和垂直重新整理,同時支援翻轉列表(四個方向)
- 提供多種重新整理指示器風格:跟隨,不跟隨,位於背部,位於前部, 提供多種載入更多風格
- 提供二樓重新整理,可實現類似淘寶二樓,微信二樓,攜程二樓
- 允許關聯指示器存放在Viewport外部,即朋友圈重新整理效果
這裡我們看下簡單的使用,這裡使用預設的上拉和下拉Widget ```Dart
class RefreshPage extends StatefulWidget { const RefreshPage({Key? key}) : super(key: key);
@override
State
class _RefreshPageState extends State
List
void _onRefresh() async{ // monitor network fetch await Future.delayed(const Duration(milliseconds: 1000)); // if failed,use refreshFailed() items = ["1", "2", "3", "4", "5", "6", "7", "8"]; _refreshController.refreshCompleted(); if(mounted) { setState(() {
});
}
}
void _onLoading() async{ // monitor network fetch await Future.delayed(const Duration(milliseconds: 1000)); // if failed,use loadFailed(),if no data return,use LoadNodata() items.add((items.length+1).toString()); if(mounted) { setState(() {
});
}
_refreshController.loadComplete();
}
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(Get.arguments['title']),), body: SmartRefresher( enablePullUp: true, controller: _refreshController, onRefresh: _onRefresh, onLoading: _onLoading, child: ListView.builder( physics: const ClampingScrollPhysics(), itemBuilder: (c, i) => Card(child: Center(child: Text(items[i],style: const TextStyle(color: Colors.black),))), itemExtent: 100.0, itemCount: items.length, ), ), ); } } ``` 下拉重新整理
上拉載入的時候enablePullUp
設定為true,我們模擬往資料中載入2條
我們也可以自定義一些
對於下拉重新整理頭我們可以使用預設WaterDropHeader
上拉重新整理的footer我們可以像案列中一樣自定義
Dart
CustomFooter get buildCustomFooter {
return CustomFooter(
builder: (BuildContext context, LoadStatus? mode) {
Widget body;
if (mode == LoadStatus.idle) {
body = const Text("pull up load");
} else if (mode == LoadStatus.loading) {
body = const CupertinoActivityIndicator();
} else if (mode == LoadStatus.failed) {
body = const Text("Load Failed!Click retry!");
} else if (mode == LoadStatus.canLoading) {
body = const Text("Release to Load more");
} else {
body = const Text("No more Data");
}
return Container(
height: 55.0,
child: Center(child: body),
);
},
);
}
這樣一個簡單的下拉重新整理和上拉載入就完成了
3. 全域性配置RefreshConfiguration
我們實際開發肯定要對其進行二次封裝,首先我們知道官方說全域性配置子樹下的SmartRefresher
```js // 全域性配置子樹下的SmartRefresher,下面列舉幾個特別重要的屬性 RefreshConfiguration( headerBuilder: () => WaterDropHeader(), // 配置預設頭部指示器,假如你每個頁面的頭部指示器都一樣的話,你需要設定這個 footerBuilder: () => ClassicFooter(), // 配置預設底部指示器 headerTriggerDistance: 80.0, // 頭部觸發重新整理的越界距離 springDescription:SpringDescription(stiffness: 170, damping: 16, mass: 1.9), // 自定義回彈動畫,三個屬性值意義請查詢flutter api maxOverScrollExtent :100, //頭部最大可以拖動的範圍,如果發生衝出檢視範圍區域,請設定這個屬性 maxUnderScrollExtent:0, // 底部最大可以拖動的範圍 enableScrollWhenRefreshCompleted: true, //這個屬性不相容PageView和TabBarView,如果你特別需要TabBarView左右滑動,你需要把它設定為true enableLoadingWhenFailed : true, //在載入失敗的狀態下,使用者仍然可以通過手勢上拉來觸發載入更多 hideFooterWhenNotFull: false, // Viewport不滿一屏時,禁用上拉載入更多功能 enableBallisticLoad: true, // 可以通過慣性滑動觸發載入更多 child: MaterialApp( ........ ) );
```
我們建立一個Widget
Dart
Widget refreshScaffold({required Widget child}) => RefreshConfiguration(
headerBuilder: () => const WaterDropHeader(), footerBuilder: () => const ClassicFooter(), child: child);
在入口包裹
這樣我們對一些頁面就不用在每個頁面配置header和footer等元件了,統一在RefreshConfiguration
設定即可。
4. 自定義封裝資料請求邏輯
我們一般分頁的時候也是對資料進行判斷處理,我們可以抽出來這個類進行處理 ```Dart enum RefreshType { refresh, loadMore }
class PagingData
PagingData(this.count, this.items);
factory PagingData.fromJson(Map
@override String toString() => '分頁: $count';
bool get isEnd => items.length >= count;
void merge(PagingData
void prepare(RefreshType refreshType) => current = refreshType == RefreshType.refresh ? 1 : (current + 1);
}
根據`RefreshType`型別,進行對應的處理
Dart
mixin RefreshMixin
List
Future
Future我們處理重新整理請求,根據請求是否是重新整理還是載入更多進行判斷,同時判斷是否是載入完成,改變狀態。
對於請求子類必須重寫。
比如我們的帖子類實現該協議,進行上拉下拉
Dart
class PostListController extends GetxController with RefreshMixin
/// 載入更多 onLoading() { startRefresh(RefreshType.loadMore).then((value) => update()); }
@override
Future``
重寫我們的
refreshRequest`這樣一個請求就處理好了
4.小結
我們在使用一些優秀的三方元件的時候可以多瞭解瞭解,有時間的話。看下其實現的思想,對於重新整理的邏輯基本就是那麼一套,我們可以根據自己開發經驗,抽出來做成公共類
。
- Flutter Module 新增到iOS專案
- Flutter學習-GetX-05 生命週期
- Flutter學習-GetX-04 依賴注入
- ios Xib 使用技巧
- 底層原理-26-Block(上)
- Flutter學習之重新整理元件-pull_to_refresh
- Flutter學習之原生通訊BasicMessageChannel
- flutter學習之嵌入原生View - android
- iOS設計模式之狀態模式
- Flutter學習之嵌入原生iOSView
- flutter學習之狀態管理Provider
- iOS設計模式之代理模式
- iOS設計模式之享元模式
- iOS設計模式之訪問者
- iOS設計模式之迭代器
- iOS設計模式之組合模式
- iOS設計模式之單例模式
- iOS設計模式之生成器模式
- 底層原理-12-dyld動態連結器載入流程
- iOS設計模式之抽象工廠