功能:
1、下拉加載
2、上拉加載
3、顯示加載圖標
4、更新列表數據,隱藏加載圖標
flutter庫:
flutter_spinkit: ^3.1.0 加載圖標
其他:加載列表需要列表,基於上一節的flutter 列表展示
細節:
1、列表構造器
a、綁定列表controller // ScrollController scrollController = ScrollController();
b、更新LIST data
2、controller監聽是否滑動到底部
@override void initState() { super.initState(); scrollController.addListener(() { if (scrollController.position.pixels == scrollController.position.maxScrollExtent) { print('滑動到了最底部${scrollController.position.pixels}'); setState(() { showMore = true; }); getMoreData(); // 增加點數據 } }); getListData(); // 暫時未使用 } @override void dispose() { super.dispose(); //手動停止滑動監聽 scrollController.dispose(); }
3、 RefreshIndicator 刷新組件
new RefreshIndicator( child: isLoading == false // 判斷是否正在加載中 ? new ListView.builder( controller: scrollController, itemCount: storyData.length, //列表長度+底部加載中提示 itemBuilder: (BuildContext context, int index) { // 傳入MessageData返回列表項 return new StoryItem(storyData[index]); }, ) : new Stack( children: <Widget>[ new Padding( padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 35.0), child: new Center( child: SpinKitFadingCircle( color: Colors.blueAccent, size: 30.0, ), ), ), new Padding( padding: new EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0), child: new Center( child: new Text('正在加載中,莫着急哦~'), ), ), ], ), onRefresh: _onRefresh) // 刷新
4、部分異步函數
Future<void> _onRefresh() async { if (isLoading) { return; } setState(() { isLoading = true; page = 0; }); print('下拉刷新開始,page = $page'); await Future.delayed(Duration(seconds: 3), () { setState(() { isLoading = false; final arr = new StoryData( 26, 'images/story/03/cover.jpg', 'episode.26', '放課後', '終於可以和自己憧憬的同學自然的說早安。正當爽子正在為這件事感動的時候,這學期代理班導的副班導荒井一市(通稱:阿瓶)登場了,阿瓶正想要擅自決定誰來制作出席簿時,不想看到大家困擾的爽子就舉起了手…。', []); storyData.add(arr); print('下拉刷新結束,page = $page'); }); }); }
Future<void> getMoreData() async {
print('xx');
if (isLoading) {
return;
}
setState(() {
isLoading = true;
page = 0;
});
print('下拉刷新開始,page = $page');
await Future.delayed(Duration(seconds: 3), () {
setState(() {
isLoading = false;
final arr = new StoryData(
26,
'images/story/03/cover.jpg',
'episode.26',
'放課後',
'終於可以和自己憧憬的同學自然的說早安。正當爽子正在為這件事感動的時候,這學期代理班導的副班導荒井一市(通稱:阿瓶)登場了,阿瓶正想要擅自決定誰來制作出席簿時,不想看到大家困擾的爽子就舉起了手…。',
[]);
storyData.add(arr);
print('下拉刷新結束,page = $page');
});
});
}
-------------完整code-------------------
story.dart
import 'package:flutter/material.dart'; import 'story_data.dart'; import 'story_item.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; void main() => runApp(Story()); class Story extends StatefulWidget { @override _Story createState() => new _Story(); } class _Story extends State<Story> { bool isLoading = false; //是否正在請求新數據 bool showMore = false; //是否顯示底部加載中提示 bool offState = false; //是否顯示進入頁面時的圓形進度條 int page = 0; //暫時用不到 ScrollController scrollController = ScrollController(); Future<void> getMoreData() async {if (isLoading) { return; } setState(() { isLoading = true; }); print('下拉刷新開始,page = $page'); await Future.delayed(Duration(seconds: 3), () { setState(() { isLoading = false; final arr = new StoryData( 26, 'images/story/03/cover.jpg', 'episode.26', '放課後', '終於可以和自己憧憬的同學自然的說早安。正當爽子正在為這件事感動的時候,這學期代理班導的副班導荒井一市(通稱:阿瓶)登場了,阿瓶正想要擅自決定誰來制作出席簿時,不想看到大家困擾的爽子就舉起了手…。', []); storyData.add(arr); }); }); } void getListData() {} @override void initState() { super.initState(); scrollController.addListener(() { if (scrollController.position.pixels == scrollController.position.maxScrollExtent) { print('滑動到了最底部${scrollController.position.pixels}'); setState(() { showMore = true; }); getMoreData(); // 增加點數據 } }); getListData(); // 暫時未使用 } @override void dispose() { super.dispose(); //手動停止滑動監聽 scrollController.dispose(); } @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( body: new RefreshIndicator( child: isLoading == false ? new ListView.builder( controller: scrollController, itemCount: storyData.length, //列表長度+底部加載中提示 itemBuilder: (BuildContext context, int index) { // 傳入MessageData返回列表項 return new StoryItem(storyData[index]); }, ) : new Stack( children: <Widget>[ new Padding( padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 35.0), child: new Center( child: SpinKitFadingCircle( color: Colors.blueAccent, size: 30.0, ), ), ), new Padding( padding: new EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0), child: new Center( child: new Text('正在加載中,莫着急哦~'), ), ), ], ), onRefresh: _onRefresh)); } Future<void> _onRefresh() async { if (isLoading) { return; } setState(() { isLoading = true; }); print('下拉刷新開始,page = $page'); await Future.delayed(Duration(seconds: 3), () { setState(() { isLoading = false; final arr = new StoryData( 26, 'images/story/03/cover.jpg', 'episode.26', '放課後', '終於可以和自己憧憬的同學自然的說早安。正當爽子正在為這件事感動的時候,這學期代理班導的副班導荒井一市(通稱:阿瓶)登場了,阿瓶正想要擅自決定誰來制作出席簿時,不想看到大家困擾的爽子就舉起了手…。', []); storyData.add(arr); print('下拉刷新結束); }); }); } }
部分截圖:
加載完成之后,列表數據會增加相同的數據,這里沒有涉及到接口。