前言:網絡
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項目已經實現」上拉刷新和分頁加載「的功能, 若是有什麼疑問的話,留言聯繫我哦!