Flutter 流式布局列表实例+上拉加载

mac2022-06-30  85

页面变化的几种方式:

一、StatefulWidget的setState形式

先声明两个变量。

int page = 1; 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 != 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(''); //没有数据时返回空 } }

组合在一起:

//火爆专区组合 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(), ], ), ); } }

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的内容粘贴过来,

_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(), ], ), ); } }

 

转载于:https://www.cnblogs.com/joe235/p/11557772.html

最新回复(0)