Flutter 流式布局列表实例+上拉加载
页面变化的几种方式:
一、StatefulWidget的setState形式
先声明两个变量。
int page = ;
List<Map> list = [];
写了一个方法,获取数据:
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 ++;
});
});
}
然后实现页面布局
标题:
//火爆专区标题 变量的形式
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 != ){
List<Widget> listWidget = list.map((val){ //把Map类型的List包装成Widget,再放回List里,并赋值给流式布局
return InkWell(
onTap: (){},
child: Container(
width: ScreenUtil().setWidth(),
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()),
Text(
val['name'],
maxLines: ,
overflow:TextOverflow.ellipsis,
style:TextStyle(color:Colors.blueGrey,fontSize:ScreenUtil().setSp()),
),
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列
children: listWidget,
);
}else{
return Text(''); //没有数据时返回空
}
}
组合在一起:
//火爆专区组合
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 = ;
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 != ){
List<Widget> listWidget = list.map((val){ //Map循环的形式:把Map类型的List包装成Widget,再放回List里,并赋值给流式布局
return InkWell(
onTap: (){},
child: Container(
width: ScreenUtil().setWidth(),
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()),
Text(
val['name'],
maxLines: ,
overflow:TextOverflow.ellipsis,
style:TextStyle(color:Colors.blueGrey,fontSize:ScreenUtil().setSp()),
),
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列
children: listWidget,
);
}else{
return Text(''); //没有数据时返回空
}
}
//火爆专区组合
Widget _hotGoods(){
return Container(
child: Column(
children: <Widget>[
hotTitle,
_wrapList(),
],
),
);
} }
flutter_easyrefresh插件:
EasyRefresh很容易就能在Flutter应用上实现下拉刷新以及上拉加载操作,它支持几乎所有的Flutter控件,但前提是需要包裹成ScrollView。它的功能与Android的SmartRefreshLayout很相似,同样也吸取了很多三方库的优点。EasyRefresh中集成了多种风格的Header和Footer,但是它并没有局限性,你可以很轻松的自定义。使用Flutter强大的动画,甚至随便一个简单的控件也可以完成。EasyRefresh的目标是为Flutter打造一个强大,稳定,成熟的下拉刷新框架。
github:https://github.com/xuelongqy/flutter_easyrefresh
flutter_easyrefresh优点:
- 能够自定义酷炫的Header和Footer,也就是上拉和下拉的效果。
- 更新及时,不断在完善,录课截至时已经是v1.2.7版本了。
- 有一个辅导群,虽然文档不太完善,但是有辅导群和详细的案例。
- 回掉方法简单,这个具体可以看下面的例子。
引入依赖
直接在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 = ;
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 != ){
List<Widget> listWidget = list.map((val){ //Map循环的形式:把Map类型的List包装成Widget类型,再放回List里,并赋值给流式布局
return InkWell(
onTap: (){},
child: Container(
width: ScreenUtil().setWidth(),
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()),
Text(
val['name'],
maxLines: ,
overflow:TextOverflow.ellipsis,
style:TextStyle(color:Colors.blueGrey,fontSize:ScreenUtil().setSp()),
),
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列
children: listWidget,
);
}else{
return Text(''); //没有数据时返回空
}
}
//火爆专区组合
Widget _hotGoods(){
return Container(
child: Column(
children: <Widget>[
hotTitle,
_wrapList(),
],
),
);
} }
Flutter 流式布局列表实例+上拉加载的更多相关文章
- wepy小程序实现列表分页上拉加载(2)
第一篇:wepy小程序实现列表分页上拉加载(1) 本文接着上一篇内容: 4.优化-添加加载动画 (1)首先写加载动画的结构和样式 打开list.wpy文件 template结构代码: <temp ...
- wepy小程序实现列表分页上拉加载(1)
使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 列表页效果图: 1.新建列表页 (1)在pages里面新建一个list.wpy文件 初始代码 ...
- 移动端web页面列表类上拉加载,查看详情,iframe嵌套第三方页面遇到的问题以及解决办法
1.移动端上拉加载 网上有很多成熟的插件,比如iscroll.在这里介绍一下用jquery和js写的上拉加载方法.使用原生的去写上拉加载更多需要三个高度去做对比,以新闻类列表举例,首先需要整个dom的 ...
- 移动端h5列表页上拉加载更多
背景 上星期公司要求做一个回收书籍的h5给安卓用,里面有一个功能是回收记录列表.设计师那边出的稿子是没有要求分页或者是上拉刷新的,但是众所周知,列表页数据很多的情况下,h5加载是很慢的.所以我一开始是 ...
- 微信小程序开发——列表分页上拉加载封装实现(订单列表为例,订单状态改变后刷新列表滚动位置不变)
业务需求: 业务需求是给订单列表添加分页功能,也就是上拉加载这种每次只请求加载固定数量的数据. 需求分析: 对业务来说就是简单的分页上拉加载,但是对于技术实现来说,除了要处理分页数据的累加加载,还要处 ...
- RecyclerViewLoadMoreDemo【封装上拉加载功能的RecyclerView,搭配SwipeRefreshLayout实现下拉刷新】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 封装含有上拉加载功能的RecyclerView,然后搭配SwipeRefreshLayout实现下拉刷新.上拉加载功能. 在项目中将 ...
- Android5.0新特性:RecyclerView实现上拉加载更多
RecyclerView是Android5.0以后推出的新控件,相比于ListView可定制性更大,大有取代ListView之势.下面这篇博客主要来实现RecyclerView的上拉加载更多功能. 基 ...
- RecyclerView实例-实现可下拉刷新上拉加载更多并可切换线性流和瀑布流模式(1)
摘要 最近项目有个列表页需要实现线性列表和瀑布流展示的切换,首先我想到的就是上 [RecyclerView],他本身已经很好的提供了三种布局方式,只是简单做个切换应该是很简单的事情,如果要用Recyc ...
- Flutter实战视频-移动电商-35.列表页_上拉加载更多制作
35.列表页_上拉加载更多制作 右侧列表上拉加载配合类别的切换 上拉加载需要一个page参数,当点击大类或者小类的时候,这个page就要变成1 provide内定义参数 首先我们需要定义一个page的 ...
随机推荐
- oracle数据库中 impdb/expdb 详解
创建逻辑目录,该命令不会在操作系统创建真正的目录,最好以system等管理员创建.create directory dpdata as 'd:\test\dump'; 二.查看管理理员目录(同时查看操 ...
- HDU-1465-不容易系列之一(容斥)
链接: https://vjudge.net/problem/HDU-1465 题意: 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易 ...
- 将 Django 应用程序部署到生产服务器
原文出自: http://www.ibm.com/developerworks/cn/opensource/os-django/ 比较有启发性质的一篇文章,会避免很多弯路 Django 是一个基于 P ...
- 洛谷 P2038 无线网络发射器选址 题解
每日一题 day9 打卡 Analysis 这道题是个模拟,两个0~128( 注意不是1~128 )的循环枚举正方形中心点,判断正方形的边界,再用循环枚举公共场所的数量就好了. 时间复杂度 < ...
- 将Eclipse,MyEclipse等编辑器的项目管理框颜色改为护眼豆沙绿的方法
转载链接:https://blog.csdn.net/caibaoH/article/details/77005977
- CF504E Misha and LCP on Tree 后缀自动机+树链剖分+倍增
求树上两条路径的 LCP (树上每个节点代表一个字符) 总共写+调了6个多小时,终于过了~ 绝对是我写过的最复杂的数据结构了 我们对这棵树进行轻重链剖分,然后把所有的重链分正串,反串插入到广义后缀自动 ...
- OpenFOAM中的热传导?【翻译】
翻译自:CFD-online 帖子地址:http://www.cfd-online.com/Forums/openfoam/70758-conductive-heat-transfer-openfoa ...
- SpringCloud介绍及入门一
springcloud是什么 基于spring boot实现的服务治理工具包,管理和协微服务 把别人的东西拿来组合在一起,形成各种组件 微服务协调者[service registtry注册中心 Eur ...
- javaSE集合---进度2
一.集合框架 1.特点 对象封装数据,对象多了也需要存储,集合用于存储对象. 对象的个数确定可以使用数组,但是不确定的话,可以用集合,因为集合是可变长度的. 2.集合和数组的区别 数组是固定长度的,集 ...
- wcf 错误提示
wcf 不弹出错误提示,只显示“服务器处理请求时遇到错误.有关构造有效服务请求的内容,请参阅服务帮助页”,添加以下节点可以弹出错误提示. <serviceDebug includeExcepti ...