Flutter 的setState与FutureBuilder及EasyRefresh示例
阅读原文时间:2023年07月11日阅读:2

用setState改变状态

class CpwsList extends StatefulWidget {
_CpwsListState createState() => _CpwsListState();
}

class _CpwsListState extends State {
int page = ;
List hotList = [];
GlobalKey _footerKey = new GlobalKey(); //定义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);
ListnewGoodsList = (val['data']['data'] as List).cast();
print(newGoodsList);
setState(() {
hotList.addAll(newGoodsList);
});
});
}

@override
Widget build(BuildContext context) {

return Container(  
  height: ScreenUtil().setHeight(),  
  margin: EdgeInsets.only(top:),  
  child: ListView.builder(  
    itemCount: hotList.length,  
    itemBuilder: (context, index) {  
      final Map<String, dynamic> item = (hotList)\[index\];  
      return Container(  
        margin: EdgeInsets.fromLTRB(, , , ),  
        child: Column(  
          children: <Widget>\[  
            Container(  
              alignment: Alignment.centerLeft,  
              child: Text('${item\["title"\]}',style: TextStyle(fontSize: ScreenUtil().setSp()),),  
            ),  
            Container(  
              padding: EdgeInsets.only(top:),  
              alignment: Alignment.centerLeft,  
              child: Text('${item\["caseno"\]}'),  
            ),  
            Container(  
              padding: EdgeInsets.only(top:),  
              alignment: Alignment.centerLeft,  
              child: Row(  
                children: <Widget>\[  
                  Expanded(  
                    child:Text('${item\["court"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                  ),  
                  Text('${item\["judgedate"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                \],  
              ),  
            ),  
          \],

        ),  
      );  
    }  
  )  
);

}
}

再添加上拉加载和下拉刷新,代码如下:

class CpwsList extends StatefulWidget {
_CpwsListState createState() => _CpwsListState();
}

class _CpwsListState extends State {
int page = ;
List hotList = [];
GlobalKey _headerKey = new GlobalKey(); //定义key
GlobalKey _footerKey = new GlobalKey(); //定义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);
ListnewGoodsList = (val['data']['data'] as List).cast();
print(newGoodsList);
setState(() {
hotList.addAll(newGoodsList);
});
});
}

@override
Widget build(BuildContext context) {

return Container(  
  height: ScreenUtil().setHeight(),  
  margin: EdgeInsets.only(top:),  
  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(, , , ),  
        child: Column(  
          children: <Widget>\[  
            Container(  
              alignment: Alignment.centerLeft,  
              child: Text('${item\["title"\]}',style: TextStyle(fontSize: ScreenUtil().setSp()),),  
            ),  
            Container(  
              padding: EdgeInsets.only(top:),  
              alignment: Alignment.centerLeft,  
              child: Text('${item\["caseno"\]}'),  
            ),  
            Container(  
              padding: EdgeInsets.only(top:),  
              alignment: Alignment.centerLeft,  
              child: Row(  
                children: <Widget>\[  
                  Expanded(  
                    child:Text('${item\["court"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                  ),  
                  Text('${item\["judgedate"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                \],  
              ),  
            ),  
          \],

        ),  
      );  
    }  
  ),  
  onRefresh: () async {  
    await new Future.delayed(const Duration(seconds: ), () {  
      setState(() {  
          hotList.clear();  
          page = ;  
          \_getList();  
      });  
    });  
  },  
  loadMore: () async {  
    await new Future.delayed(const Duration(seconds: ), () {  
      setState(() {  
          page++;  
          \_getList();  
      });  
    });  
  },

  )  
);

}
}

异步请求再渲染 不用setState改变状态

class CpwsList extends StatefulWidget {
_CpwsListState createState() => _CpwsListState();
}

class _CpwsListState extends State {
@override
Widget build(BuildContext context) {
var formData = {'isDebug':'aa'};
return Container(
height: ScreenUtil().setHeight(),
margin: EdgeInsets.only(top:),
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(, , , ),  
                child: Column(  
                children: <Widget>\[  
                  Container(  
                    alignment: Alignment.centerLeft,  
                    child: Text('${item\["title"\]}',style: TextStyle(fontSize: ScreenUtil().setSp()),),  
                  ),  
                  Container(  
                    padding: EdgeInsets.only(top:),  
                    alignment: Alignment.centerLeft,  
                    child: Text('${item\["caseno"\]}'),  
                  ),  
                  Container(  
                    padding: EdgeInsets.only(top:),  
                    alignment: Alignment.centerLeft,  
                    child: Row(  
                      children: <Widget>\[  
                        Expanded(  
                          child:Text('${item\["court"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                        ),  
                        Text('${item\["judgedate"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),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);
ListnewGoodsList = (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 {
Future getDataFuture;
int page = ;
List hotList = [];
GlobalKey _headerKey = new GlobalKey(); //定义key
GlobalKey _footerKey = new GlobalKey(); //定义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);
ListnewGoodsList = (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(),  
  margin: EdgeInsets.only(top:),  
  child: FutureBuilder( //异步请求再渲染 不用setState改变状态  
    future: getDataFuture,  
    builder: (context,AsyncSnapshot async){  
       //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(, , , ),  
                  child: Column(  
                  children: <Widget>\[  
                    Container(  
                      alignment: Alignment.centerLeft,  
                      child: Text('${item\["title"\]}',style: TextStyle(fontSize: ScreenUtil().setSp()),),  
                    ),  
                    Container(  
                      padding: EdgeInsets.only(top:),  
                      alignment: Alignment.centerLeft,  
                      child: Text('${item\["caseno"\]}'),  
                    ),  
                    Container(  
                      padding: EdgeInsets.only(top:),  
                      alignment: Alignment.centerLeft,  
                      child: Row(  
                        children: <Widget>\[  
                          Expanded(  
                            child:Text('${item\["court"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                          ),  
                          Text('${item\["judgedate"\]}',style: TextStyle(fontSize: ScreenUtil().setSp(),color:Colors.black38)),  
                        \],  
                      ),  
                    ),  
                  \],

                ),  
                );  
              }  
            ),  
            onRefresh: () async {  
              await new Future.delayed(const Duration(seconds: ), () {  
                setState(() {  
                    hotList.clear();  
                    page = ;  
                    getDataFuture = \_getList();  
                });  
              });  
            },  
            loadMore: () async {  
              await new Future.delayed(const Duration(seconds: ), () {  
                setState(() {  
                    page++;  
                    getDataFuture = \_getList();  
                });  
              });  
            },  
          );

       }else{  
          return Center(  
            child: Text('加载中...'),  
          );  
       }  
     }  
  ),  
);  

}
}

注意:getDataFuture = _getList();

最后把子项剥离出来,单独写一个Widget,方便InkWell。

Widget _cpwsitem(Map item, index) {
return InkWell(
onTap: () {},
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,
child: Text(
'${item["title"]}',
style: TextStyle(fontSize: ScreenUtil().setSp()),
),
),
Container(
padding: EdgeInsets.only(top: ),
alignment: Alignment.centerLeft,
child: Text('${item["caseno"]}'),
),
Container(
padding: EdgeInsets.only(top: ),
alignment: Alignment.centerLeft,
child: Row(
children: [
Expanded(
child: Text(
'${item["court"]}',
style: TextStyle(fontSize: ScreenUtil().setSp(), color: Colors.black38)
),
),
Text(
'${item["judgedate"]}',
style: TextStyle(fontSize: ScreenUtil().setSp(), color: Colors.black38)
),
],
),
),
],
),
);
}

然后把上面Container的child改为:

child: _cpwsitem(item, index)