功能:
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(\'下拉刷新结束); }); }); } }
部分截图:
加载完成之后,列表数据会增加相同的数据,这里没有涉及到接口。