Flutter 的setState與FutureBuilder及EasyRefresh示例
- 2019 年 10 月 11 日
- 筆記
用setState改變狀態
class CpwsList extends StatefulWidget { _CpwsListState createState() => _CpwsListState(); } class _CpwsListState extends State<CpwsList> { int page = 1; List<Map> hotList = []; GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); //定義key var scrollController = new ScrollController(); //聲明控制器變量 @override void initState() { super.initState(); _getList(); } void _getList(){ var formData = {'page':page, 'isDebug':'aa'}; request('get', 'cpwsList', formData: formData).then((val){ var data = val.toString(); //print(data); List<Map>newGoodsList = (val['data']['data'] as List).cast(); print(newGoodsList); setState(() { hotList.addAll(newGoodsList); }); }); } @override Widget build(BuildContext context) { return Container( height: ScreenUtil().setHeight(1000), margin: EdgeInsets.only(top:15), child: ListView.builder( itemCount: hotList.length, itemBuilder: (context, index) { final Map<String, dynamic> item = (hotList)[index]; return Container( margin: EdgeInsets.fromLTRB(15, 20, 15, 10), child: Column( children: <Widget>[ Container( alignment: Alignment.centerLeft, child: Text('${item["title"]}',style: TextStyle(fontSize: ScreenUtil().setSp(30)),), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Text('${item["caseno"]}'), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Row( children: <Widget>[ Expanded( child:Text('${item["court"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ), Text('${item["judgedate"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ], ), ), ], ), ); } ) ); } }
再添加上拉加載和下拉刷新,代碼如下:
class CpwsList extends StatefulWidget { _CpwsListState createState() => _CpwsListState(); } class _CpwsListState extends State<CpwsList> { int page = 1; List<Map> hotList = []; GlobalKey<RefreshHeaderState> _headerKey = new GlobalKey<RefreshHeaderState>(); //定義key GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); //定義key var scrollController = new ScrollController(); //聲明控制器變量 @override void initState() { super.initState(); _getList(); } void _getList(){ var formData = {'page':page, 'isDebug':'aa'}; request('get', 'cpwsList', formData: formData).then((val){ var data = val.toString(); //print(data); List<Map>newGoodsList = (val['data']['data'] as List).cast(); print(newGoodsList); setState(() { hotList.addAll(newGoodsList); }); }); } @override Widget build(BuildContext context) { return Container( height: ScreenUtil().setHeight(1000), margin: EdgeInsets.only(top:15), child: EasyRefresh( refreshHeader: ClassicsHeader(//自定義下拉刷新效果 key:_headerKey, bgColor:Colors.white, textColor: Colors.blueGrey, moreInfoColor: Colors.blueGrey, refreshingText: '加載中', //加載時顯示的文字 refreshedText: '刷新成功', ), refreshFooter:ClassicsFooter( //自定義上拉加載效果 key:_footerKey, bgColor:Colors.white, textColor: Colors.blueGrey, moreInfoColor: Colors.blueGrey, showMore: true, noMoreText: '', moreInfo: '加載中', //加載時顯示的文字 loadReadyText: '上拉加載...', //準備時顯示的文字 ), child: ListView.builder( itemCount: hotList.length, itemBuilder: (context, index) { final Map<String, dynamic> item = (hotList)[index]; return Container( margin: EdgeInsets.fromLTRB(15, 20, 15, 10), child: Column( children: <Widget>[ Container( alignment: Alignment.centerLeft, child: Text('${item["title"]}',style: TextStyle(fontSize: ScreenUtil().setSp(30)),), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Text('${item["caseno"]}'), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Row( children: <Widget>[ Expanded( child:Text('${item["court"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ), Text('${item["judgedate"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ], ), ), ], ), ); } ), onRefresh: () async { await new Future.delayed(const Duration(seconds: 1), () { setState(() { page = 1; _getList(); }); }); }, loadMore: () async { await new Future.delayed(const Duration(seconds: 1), () { setState(() { page++; _getList(); }); }); }, ) ); } }
異步請求再渲染 不用setState改變狀態
class CpwsList extends StatefulWidget { _CpwsListState createState() => _CpwsListState(); } class _CpwsListState extends State<CpwsList> { @override Widget build(BuildContext context) { var formData = {'isDebug':'aa'}; return Container( height: ScreenUtil().setHeight(1000), margin: EdgeInsets.only(top:15), child: FutureBuilder( //異步請求再渲染 不用setState改變狀態 future: request('get','cpwsList',formData:formData), //可選參數formData:formData=屬性名:屬性值 builder: (context, snapshot){ //snapshot就是_calculation在時間軸上執行過程的狀態快照 if(snapshot.hasData){ //判斷有沒有值 //print(snapshot.data); //數據處理 var data = snapshot.data; List<Map> cpwsData = (data['data']['data'] as List).cast(); //print(chinaData); return ListView.builder( itemCount: cpwsData.length, itemBuilder: (context, index) { final Map<String, dynamic> item = (cpwsData)[index]; return Container( margin: EdgeInsets.fromLTRB(15, 20, 15, 10), child: Column( children: <Widget>[ Container( alignment: Alignment.centerLeft, child: Text('${item["title"]}',style: TextStyle(fontSize: ScreenUtil().setSp(30)),), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Text('${item["caseno"]}'), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Row( children: <Widget>[ Expanded( child:Text('${item["court"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ), Text('${item["judgedate"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ], ), ), ], ), ); } ); }else{ return Center( child: Text('加載中...'), ); } } ), ); } }
EasyRefresh + ScrollController 實現下拉刷新和上拉加載
FutureBuilder 需要結合 Future 使用,先定義一個 Future,異步網絡請求。
///先定義一個 Future Future getDataFuture; ... @override void initState() { super.initState(); getDataFuture = _getList(); } //獲取數據 Future _getList() async{ var formData = {'page':page, 'isDebug':'aa'}; var response = await request('get', 'cpwsList', formData: formData); //print(response); List<Map>newGoodsList = (response['data']['data'] as List).cast(); //print(newGoodsList); if(newGoodsList != null){ hotList.addAll(newGoodsList); } return hotList; }
通過 ScrollController 可以判斷滾動列表是否滾動到底部,如果是,就調用上滑加載的功能獲取數據即可。
var scrollController = new ScrollController(); //聲明控制器變量
添加上拉加載及下拉刷新代碼:
class CpwsList extends StatefulWidget { _CpwsListState createState() => _CpwsListState(); } class _CpwsListState extends State<CpwsList> { Future getDataFuture; int page = 1; List<Map> hotList = []; GlobalKey<RefreshHeaderState> _headerKey = new GlobalKey<RefreshHeaderState>(); GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); //定義key var scrollController = new ScrollController(); //聲明控制器變量 @override void initState() { super.initState(); getDataFuture = _getList(); } //獲取數據 Future _getList() async{ var formData = {'page':page, 'isDebug':'aa'}; var response = await request('get', 'cpwsList', formData: formData); //print(response); List<Map>newGoodsList = (response['data']['data'] as List).cast(); //print(newGoodsList); if(newGoodsList != null){ hotList.addAll(newGoodsList); } return hotList; } @override Widget build(BuildContext context) { return Container( height: ScreenUtil().setHeight(1000), margin: EdgeInsets.only(top:15), child: FutureBuilder( //異步請求再渲染 不用setState改變狀態 future: getDataFuture, builder: (context,AsyncSnapshot async){ //snapshot就是_calculation在時間軸上執行過程的狀態快照 print(async.hasData); if(async.hasData){ //判斷有沒有值 return EasyRefresh( refreshHeader: ClassicsHeader(//自定義下拉刷新效果 key:_headerKey, bgColor:Colors.white, textColor: Colors.blueGrey, moreInfoColor: Colors.blueGrey, refreshingText: '加載中', //加載時顯示的文字 refreshedText: '刷新成功', ), refreshFooter: ClassicsFooter( //自定義refreshFooter key: _footerKey, bgColor: Colors.white, textColor: Colors.blueGrey, moreInfoColor: Colors.blueGrey,//加載時顯示的文字顏色 showMore: true, noMoreText: '', moreInfo: '加載中', //加載時顯示的文字 loadReadyText: '上拉加載...', //準備文字 ), child: ListView.builder( controller: scrollController, itemCount: hotList.length, itemBuilder: (context, index) { final Map<String, dynamic> item = (hotList)[index]; return Container( margin: EdgeInsets.fromLTRB(15, 20, 15, 10), child: Column( children: <Widget>[ Container( alignment: Alignment.centerLeft, child: Text('${item["title"]}',style: TextStyle(fontSize: ScreenUtil().setSp(30)),), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Text('${item["caseno"]}'), ), Container( padding: EdgeInsets.only(top:5), alignment: Alignment.centerLeft, child: Row( children: <Widget>[ Expanded( child:Text('${item["court"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ), Text('${item["judgedate"]}',style: TextStyle(fontSize: ScreenUtil().setSp(22),color:Colors.black38)), ], ), ), ], ), ); } ), onRefresh: () async { await new Future.delayed(const Duration(seconds: 1), () { setState(() { page = 1; _getList(); }); }); }, loadMore: () async{ setState(() { page++; _getList(); }); } ); }else{ return Center( child: Text('加載中...'), ); } } ), ); } }