先声明两个变量。git
int page = 1; List<Map> list = [];
写了一个方法,获取数据:github
void _getHotGoods(){ var formData = {'page':page}; request('post', 'homePageBelowConten',formData: formData).then((val){ var data = json.decode(val.toString()); List<Map> newList = (data['data'] as List).cast(); setState(() { list.addAll(newList); //新的列表加到老的列表之上 page ++; }); }); }
而后实现页面布局json
标题:框架
//火爆专区标题 变量的形式 Widget hotTitle = Container( margin: EdgeInsets.only(top: 10.0), alignment: Alignment.center, color: Colors.transparent, //透明背景色 padding: EdgeInsets.all(5.0), child: Text('火爆专区'), );
每一个子项:async
//火爆专区子项 方法的形式 Widget _wrapList(){ if(list.length != 0){ List<Widget> listWidget = list.map((val){ //把Map类型的List包装成Widget,再放回List里,并赋值给流式布局 return InkWell( onTap: (){}, child: Container( width: ScreenUtil().setWidth(372), color: Colors.white, padding: EdgeInsets.all(5.0), margin: EdgeInsets.only(bottom: 3.0), child: Column( children: <Widget>[ Image.network(val['image'],width:ScreenUtil().setWidth(370)), Text( val['name'], maxLines: 1, overflow:TextOverflow.ellipsis, style:TextStyle(color:Colors.blueGrey,fontSize:ScreenUtil().setSp(26)), ), Row( children: <Widget>[ Text('¥${val['mallPrice']}'), Text( '¥${val['price']}', style: TextStyle(color: Colors.black26,decoration: TextDecoration.lineThrough), ) ], ), ], ), ), ); }).toList(); //把Map类型的List包装成Widget,再放回List里,并赋值给流式布局 return Wrap( //返回流式布局 spacing: 2, //每行2列 children: listWidget, ); }else{ return Text(''); //没有数据时返回空 } }
组合在一块儿:ide
//火爆专区组合 Widget _hotGoods(){ return Container( child: Column( children: <Widget>[ hotTitle, _wrapList(), ], ), ); }
完整代码:布局
import 'package:flutter/material.dart'; import '../service/service_method.dart'; import 'dart:convert'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class CategoryPage extends StatefulWidget { _CategoryPageState createState() => _CategoryPageState(); } class _CategoryPageState extends State<CategoryPage> { int page = 1; List<Map> list = []; @override void initState() { super.initState(); _getHotGoods(); //火爆专区获取值 } @override Widget build(BuildContext context) { return SingleChildScrollView( child:Column( children: <Widget>[ _hotGoods(), ], ), ); } //火爆商品接口 void _getHotGoods(){ var formData = {'page':page}; //Map类型 request('post', 'homePageBelowConten',formData: formData).then((val){ var data = json.decode(val.toString()); List<Map> newList = (data['data'] as List).cast(); setState(() { list.addAll(newList); //新的列表加到老的列表之上 page ++; }); }); } //火爆专区标题 变量的形式 Widget hotTitle = Container( margin: EdgeInsets.only(top: 10.0), alignment: Alignment.center, color: Colors.transparent, //透明背景色 padding: EdgeInsets.all(5.0), child: Text('火爆专区'), ); //火爆专区子项 方法的形式 Widget _wrapList(){ if(list.length != 0){ List<Widget> listWidget = list.map((val){ //Map循环的形式:把Map类型的List包装成Widget,再放回List里,并赋值给流式布局 return InkWell( onTap: (){}, child: Container( width: ScreenUtil().setWidth(372), color: Colors.white, padding: EdgeInsets.all(5.0), margin: EdgeInsets.only(bottom: 3.0), child: Column( children: <Widget>[ Image.network(val['image'],width:ScreenUtil().setWidth(370)), Text( val['name'], maxLines: 1, overflow:TextOverflow.ellipsis, style:TextStyle(color:Colors.blueGrey,fontSize:ScreenUtil().setSp(26)), ), Row( children: <Widget>[ Text('¥${val['mallPrice']}'), Text( '¥${val['price']}', style: TextStyle(color: Colors.black26,decoration: TextDecoration.lineThrough), ) ], ), ], ), ), ); }).toList(); //Map循环的形式:把Map类型的List包装成Widget,再放回List里,并赋值给流式布局 return Wrap( //返回流式布局 spacing: 2, //每行2列 children: listWidget, ); }else{ return Text(''); //没有数据时返回空 } } //火爆专区组合 Widget _hotGoods(){ return Container( child: Column( children: <Widget>[ hotTitle, _wrapList(), ], ), ); } }
EasyRefresh很容易就能在Flutter应用上实现下拉刷新以及上拉加载操做,它支持几乎全部的Flutter控件,但前提是须要包裹成ScrollView。它的功能与Android的SmartRefreshLayout很类似,一样也吸收了不少三方库的优势。EasyRefresh中集成了多种风格的Header和Footer,可是它并无局限性,你能够很轻松的自定义。使用Flutter强大的动画,甚至随便一个简单的控件也能够完成。EasyRefresh的目标是为Flutter打造一个强大,稳定,成熟的下拉刷新框架。post
github:https://github.com/xuelongqy/flutter_easyrefresh学习
flutter_easyrefresh优势:动画
引入依赖
直接在pubspec.yaml
中的dependencies
中进行引入,主要要用最新版本,文章中的版本不必定是最新版本。
flutter_easyrefresh: ^1.2.7
引入后,在要使用的页面用import
引入package
,代码以下:
import 'package:flutter_easyrefresh/easy_refresh.dart';
制做上拉加载效果
使用这个插件,要求咱们必须是一个ListView,因此咱们要改造之前的代码,SingleChildScrollView改形成ListView。并添加loadMore,把_getHotGoods的内容粘贴过来,
return EasyRefresh( child:ListView( children: <Widget>[ _hotGoods(), ], ), loadMore: () async{ var formData = {'page':page}; //Map类型 await request('post', 'homePageBelowConten',formData: formData).then((val){ var data = json.decode(val.toString()); List<Map> newList = (data['data'] as List).cast(); setState(() { list.addAll(newList); //新的列表加到老的列表之上 page ++; }); }); }, );
如今运行已经能够看到效果了,不过还须要修改下。
自定义上拉加载效果
由于它自带的样式是蓝色的,与咱们的界面不太相符,因此咱们改造一下,它的底部上拉刷新效果。若是你有兴趣作出更炫酷的效果,能够自行查看一下Github,学习一下。
refreshFooter:ClassicsFooter( //自定义上拉加载效果 key:_footerKey, bgColor:Colors.white, textColor: Colors.blueGrey, moreInfoColor: Colors.blueGrey, showMore: true, noMoreText: '', moreInfo: '加载中', //加载时显示的文字 loadReadyText: '上拉加载...', //准备时显示的文字 ),
还要在上面定义Key:
GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); //定义key
完整代码:
import 'package:flutter/material.dart'; import '../service/service_method.dart'; import 'dart:convert'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; class CategoryPage extends StatefulWidget { _CategoryPageState createState() => _CategoryPageState(); } class _CategoryPageState extends State<CategoryPage> { int page = 1; List<Map> list = []; GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); //定义key @override void initState() { super.initState(); //_getHotGoods(); //火爆专区获取值 } @override Widget build(BuildContext context) { return EasyRefresh( refreshFooter:ClassicsFooter( //自定义上拉加载效果 key:_footerKey, bgColor:Colors.white, textColor: Colors.blueGrey, moreInfoColor: Colors.blueGrey, showMore: true, noMoreText: '', moreInfo: '加载中', //加载时显示的文字 loadReadyText: '上拉加载...', //准备时显示的文字 ), child:ListView( children: <Widget>[ _hotGoods(), ], ), loadMore: () async{ var formData = {'page':page}; //Map类型 await request('post', 'homePageBelowConten',formData: formData).then((val){ var data = json.decode(val.toString()); List<Map> newList = (data['data'] as List).cast(); setState(() { list.addAll(newList); //新的列表加到老的列表之上 page ++; }); }); }, ); } //火爆商品接口 // void _getHotGoods(){ // var formData = {'page':page}; //Map类型 // request('post', 'homePageBelowConten',formData: formData).then((val){ // var data = json.decode(val.toString()); // List<Map> newList = (data['data'] as List).cast(); // setState(() { // list.addAll(newList); //新的列表加到老的列表之上 // page ++; // }); // }); // } //火爆专区标题 变量的形式 Widget hotTitle = Container( margin: EdgeInsets.only(top: 10.0), alignment: Alignment.center, color: Colors.transparent, //透明背景色 padding: EdgeInsets.all(5.0), child: Text('火爆专区'), ); //火爆专区子项 方法的形式 Widget _wrapList(){ if(list.length != 0){ List<Widget> listWidget = list.map((val){ //Map循环的形式:把Map类型的List包装成Widget类型,再放回List里,并赋值给流式布局 return InkWell( onTap: (){}, child: Container( width: ScreenUtil().setWidth(372), color: Colors.white, padding: EdgeInsets.all(5.0), margin: EdgeInsets.only(bottom: 3.0), child: Column( children: <Widget>[ Image.network(val['image'],width:ScreenUtil().setWidth(370)), Text( val['name'], maxLines: 1, overflow:TextOverflow.ellipsis, style:TextStyle(color:Colors.blueGrey,fontSize:ScreenUtil().setSp(26)), ), Row( children: <Widget>[ Text('¥${val['mallPrice']}'), Text( '¥${val['price']}', style: TextStyle(color: Colors.black26,decoration: TextDecoration.lineThrough), ) ], ), ], ), ), ); }).toList(); //Map循环的形式:把Map类型的List包装成Widget类型,再放回List里,并赋值给流式布局 return Wrap( //返回流式布局 spacing: 2, //每行2列 children: listWidget, ); }else{ return Text(''); //没有数据时返回空 } } //火爆专区组合 Widget _hotGoods(){ return Container( child: Column( children: <Widget>[ hotTitle, _wrapList(), ], ), ); } }