Flutter 中下拉刷新需要用到 RefreshIndicator 組件京髓,一般在 ScrollView 或 ListView 外包一層 RefreshIndicator 組件即可私蕾。
1. 常見用法
Future _onRefresh() async {
//......實現(xiàn)刷新邏輯
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: _onRefresh,
child: SingleChildScrollView(
child: Container(),
));
}
使用很簡單净响,只需要實現(xiàn) onRefresh 函數(shù)即可废累,這也是一個 Future 函數(shù)十气,當(dāng)該 Future 執(zhí)行完畢時丧蘸,刷新操作也就完成了。是不是很奇怪祖乳,當(dāng)我們用原生代碼寫下拉刷新時逗堵,通常需要定義一個狀態(tài)來表示刷新狀態(tài),到 Flutter 這里居然啥都不用管眷昆。當(dāng)觸發(fā)下拉刷新時蜒秤,就會執(zhí)行 onRefresh 函數(shù),只要該函數(shù)沒有執(zhí)行完畢亚斋,UI 上就一直顯示的是刷新狀態(tài)作媚,一旦該函數(shù)執(zhí)行完畢,UI 狀態(tài)也會自動改變成刷新完成帅刊。
2. 怎么觸發(fā)自動刷新
通常我們進入某個頁面時纸泡,希望一進去就會觸發(fā)自動下拉刷新,但是找了一圈發(fā)現(xiàn)沒有什么屬性可設(shè)置厚掷。經(jīng)過一番研究弟灼,發(fā)現(xiàn) RefreshIndicator 也是一個有狀態(tài)組件,我們可直接獲取該組件的狀態(tài)冒黑,通過它的狀態(tài)來手動觸發(fā)下拉刷新。這就需要用到每個 Widget 都會有的 Key
屬性了勤哗,通過 key 可以得到其對應(yīng)的狀態(tài)抡爹。具體代碼如下:
//自定義 RefreshIndicatorState 類型的 Key
final GlobalKey<RefreshIndicatorState> _refreshKey = GlobalKey();
@override
void initState() {
super.initState();
//必須在組件掛載運行的第一幀后執(zhí)行,否則 _refreshKey 還沒有與組件狀態(tài)關(guān)聯(lián)起來
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
//關(guān)鍵代碼芒划,直接觸發(fā)下拉刷新
_refreshKey.currentState?.show();
});
}
Future _onRefresh() async {
//......實現(xiàn)刷新邏輯
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
key: _refreshKey, //自定義 key冬竟,需要通過 key 獲取到對應(yīng)的 State
onRefresh: _onRefresh,
child: SingleChildScrollView(
child: Container(),
));
}
3. 頁面不能滾動時無法觸發(fā)下拉刷新
如果頁面內(nèi)容很少,在一屏內(nèi)不能滾動民逼,你會發(fā)現(xiàn)無法觸發(fā)下拉刷新泵殴。解決這個問題,需要設(shè)置 ScrollView 的 physics 屬性拼苍。
最終完整解決方案如下:
//自定義 RefreshIndicatorState 類型的 Key
final GlobalKey<RefreshIndicatorState> _refreshKey = GlobalKey();
@override
void initState() {
super.initState();
//必須在組件掛載運行的第一幀后執(zhí)行笑诅,否則 _refreshKey 還沒有與組件狀態(tài)關(guān)聯(lián)起來
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
//關(guān)鍵代碼,直接觸發(fā)下拉刷新
_refreshKey.currentState?.show();
});
}
Future _onRefresh() async {
//......實現(xiàn)刷新邏輯
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
key: _refreshKey, //自定義 key疮鲫,需要通過 key 獲取到對應(yīng)的 State
onRefresh: _onRefresh,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Container(),
));
}
默認情況下吆你,當(dāng) ScrollView 包裹的內(nèi)容太少時,是不會觸發(fā)滾動事件的俊犯,這樣也就不會觸發(fā)下拉刷新妇多。AlwaysScrollableScrollPhysics
則可以在這種情況下,觸發(fā)滾動事件燕侠。