前言:网络
Flutter项目须要实现“上拉刷新和分页加载“的功能,分页能够把大量数据分割成一个个小段,分次加载。这样能够有效避免由于一次load所有数据而致使客户端变慢的问题。在这里我使用EasyRefresh第三方插件来实现下拉刷新和分页加载的操做。async
用到的知识点:ide
实现的步骤:工具
1.在pubspec.yaml添加sdkflex
dependencies: ... cupertino_icons: ^0.1.0 dio: ^2.1.9 scoped_model: ^1.0.1 flutter_easyrefresh: ^1.2.7
2.请求数据ui
//请求数据的方法 Future getListData(BuildContext context) async { String url = IHttpService.baseUrl +"&offset=$currentPage&limit=$limit"; //接口 DioUtil.getInstance().get(context, url).then((res) { //DioUtil是自定义封装网络请求的工具类 if (res.statusCode == Response.ok) { var responseList = res.data; if (responseList != null) { _listData = responseList["loans"]; } } else { _listData= []; } }).catchError((onError) { }).whenComplete(this.notifyListeners); }
3.上拉刷新数据this
//上拉刷新数据的方法 Future refreshData(BuildContext context) async { currentPage = 1; _listData.clear(); getListData(context); return null; }
4.加载更多数据url
//加载更多数据的方法 Future loadMoreData(BuildContext context) async { page += 1;//每次加载的条数 String url = IHttpService.baseUrl +"&offset=$currentPage&limit=$limit"; //接口 DioUtil.getInstance().get(context, url).then((res) { if (res.statusCode == Response.ok) { var responseList = res.data; if (responseList != null) { var listData = responseList["loans"]; List list1 = List(); list1.addAll(_listData); list1.addAll(listData); _listData= list1; } } else { _listData= []; } }).catchError((onError) { }).whenComplete(this.notifyListeners); }
5.easyrefresh实现下拉刷新,分页加载插件
Widget _buildListView(BuildContext context, CommonStateModel model) { return new EasyRefresh( onRefresh: () => _onListRefresh(context), //下拉刷新 loadMore: () => _onListLoadMore(context), //分页加载更多 key: _easyRefreshKey, refreshHeader: MaterialHeader( //Material风格的头部刷新 key: _headerKey, ), refreshFooter: MaterialFooter( //Material风格的底部刷新 key: _footerKey, ), child: _buildListViewContent(context, model), ); }
6.listview展现列表信息code
Widget _buildListViewContent(BuildContext context, CommonStateModel model) { return ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return renderRow(context, model, index); }, itemCount: model.listData.length, controller: _scrollController, ); } //自定义的列表项 Widget renderRow(BuildContext context, CommonStateModel model, int i) { var itemData = model.listData[i]; return new InkWell( child: new Container( decoration: new BoxDecoration(color: Colors.white), margin: const EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), child: new Row( children: <Widget>[ new Expanded( flex: 1, child: new Padding( padding: const EdgeInsets.all(5.0), child: new Container( height: 120.0, child: new Center( child: Image.asset(images/logo.png), ), ), )), new Expanded( flex: 2, child: new Padding( padding: const EdgeInsets.all(5.0), child: new Column( children: <Widget>[ new Text(itemData["name"]) ... ], ), ), ), new Image.asset("images/arrow_right_icon.png", height: 25.0, width: 25.0) ], ), ), onTap: () { //To do something }, ); }
7.Model层封装“上拉刷新和分页加载“的完整代码
import 'package:scoped_model/scoped_model.dart'; class CommonStateModel extends Model { int currentPage = 1; int limit = 4; //每次分页加载的条数 var _listData; get listData => _listData; //请求数据的方法 Future getListData(BuildContext context) async { //接口 String url = IHttpService.baseUrl +"&offset=$currentPage&limit=$limit"; //接口 DioUtil.getInstance().get(context, url).then((res) { //DioUtil是自定义封装网络请求的工具类 if (res.statusCode == Response.ok) { var responseList = res.data; if (responseList != null) { _listData = responseList["loans"]; } } else { _listData= []; } }).catchError((onError) { }).whenComplete(this.notifyListeners); } //上拉刷新数据的方法 Future refreshData(BuildContext context) async { currentPage = 1; _listData.clear(); getListData(context); return null; } //加载更多数据的方法 Future loadMoreData(BuildContext context) async { page += 1;//每次分页加载的条数 String url = IHttpService.baseUrl +"&offset=$currentPage&limit=$limit"; //接口 DioUtil.getInstance().get(context, url).then((res) { if (res.statusCode == Response.ok) { var responseList = res.data; if (responseList != null) { var listData = responseList["loans"]; List list1 = List(); list1.addAll(_listData); list1.addAll(listData); _listData= list1; } } else { _listData= []; } }).catchError((onError) { }).whenComplete(this.notifyListeners); } static CommonStateModel of(context) => ScopedModel.of<CommonStateModel>(context, rebuildOnChange: true); }
8.UI层实现上拉刷新和分页加载的完整代码
import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_easyrefresh/material_header.dart'; import 'package:flutter_easyrefresh/material_footer.dart'; import 'package:scoped_model/scoped_model.dart'; ... class HomePage extends StatefulWidget { @override State<StatefulWidget> createState() => HomePageState(); } class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin { CommonStateModel commonStateModel; GlobalKey<EasyRefreshState> _easyRefreshKey = new GlobalKey<EasyRefreshState>(); GlobalKey<RefreshHeaderState> _headerKey = new GlobalKey<RefreshHeaderState>(); GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); ScrollController _scrollController = ScrollController(); _getModel() { if (commonStateModel == null) { commonStateModel = CommonStateModel(); } return commonStateModel; } //请求数据的方法 void _initListData(BuildContext context) async { await commonStateModel.getListData(context); } //上拉刷新的方法 Future<Null> _onListRefresh(BuildContext context) async { await commonStateModel.refreshData(context); } //分页加载更多的方法 Future<Null> _onListLoadMore(BuildContext context) async { await commonStateModel.loadMoreData(context); } @override void initState() { super.initState(); _getModel(); _initListData(context); } @override Widget build(BuildContext context) { super.build(context); return ScopedModel<CommonStateModel>( model: commonStateModel, child: ScopedModelDescendant<CommonStateModel>( builder: (context, child, model) { return Scaffold( body: Container( decoration: new BoxDecoration(color: Color(0xFFECECEB)), child: _buildListView(context, model), ), ); }, ), ); } //使用easyrefresh实现下拉刷新,分页加载的方法 Widget _buildListView(BuildContext context, CommonStateModel model) { return new EasyRefresh( onRefresh: () => _onListRefresh(context), loadMore: () => _onListLoadMore(context), key: _easyRefreshKey, refreshHeader: MaterialHeader( //Material风格的头部刷新 key: _headerKey, ), refreshFooter: MaterialFooter( //Material风格的底部刷新 key: _footerKey, ), child: _buildListViewContent(context, model), ); } //listview展现列表信息的方法 Widget _buildListViewContent(BuildContext context, CommonStateModel model) { return ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return renderRow(context, model, index); }, itemCount: model.listData.length, controller: _scrollController, ); } Widget renderRow(BuildContext context, CommonStateModel model, int i) { var itemData = model.listData[i]; return new InkWell( child: new Container( decoration: new BoxDecoration(color: Colors.white), margin: const EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), child: new Row( children: <Widget>[ new Expanded( flex: 1, child: new Padding( padding: const EdgeInsets.all(5.0), child: new Container( height: 120.0, child: new Center( child: Image.asset(Image.asset(images/logo.png)), ), ), )), new Expanded( flex: 2, child: new Padding( padding: const EdgeInsets.all(5.0), child: new Column( children: <Widget>[ new Text[itemData["name"]] ... ], ), ), ), new Image.asset("images/arrow_right_icon.png", height: 25.0, width: 25.0) ], ), ), onTap: () { //To do something }, ); } @override void dispose() { super.dispose(); _scrollController.dispose(); } @protected bool get wantKeepAlive => true; }
9.总结:
在Flutter项目已经实现”上拉刷新和分页加载“的功能, 若是有什么疑问的话,留言联系我哦!