Flutter APP 中实现瀑布流布局展示商品信息。效果图:
Flutter自带的网格布局部件固定了每个子部件的高度,不能实现我们的需求。GridView 部件:如下图所示:
要想实现瀑布流效果需要使用第三方包: flutter_staggered_grid_view
为了便于代码的阅读和拓展,减少嵌套理清业务逻辑(文邹邹的理论。。。),实际上就是把 GridView部件的父级页面和他的子项布局写在两个文件里面。
这里面主要实例化封装好的 Dio 类来请求获取商品数据和编写父别页面布局。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:oblivion/public.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:oblivion/widgets/square_card.dart';
import 'package:oblivion/model/CardModel.dart';
class CardPage extends StatefulWidget {
@override
_CardPageState createState() => _CardPageState();
}
class _CardPageState extends State<CardPage> {
List cardList;
//获取商品数据
Future getSquarePageContent() async{
DioManager.getInstance().postNoParams(ServiceUrl.getCards,(data) {
setState(() {
//商品列表
cardList =(data['data']['cards'] as List).cast();
});
}, (error) {
print("接口异常:" + error);
});
}
@override
void initState() {
// TODO: implement initState
getSquarePageContent();
super.initState();
}
//下拉刷新方法
Future<void> _onRefresh() async {
print("_onRefresh");
}
//上拉加载方法
Future<void> _onLoadMore() async {
print("_onLoadMore");
}
@override
Widget build(BuildContext context) {
if(cardList == null){
return Text('没有数据');
}else{
return Container(
height: ScreenUtil().setHeight(1500),
padding:EdgeInsets.all(3.0),
child: StaggeredGridView.countBuilder(
padding: EdgeInsets.all(8),
crossAxisCount: 4,
itemCount: cardList.length,
//核心代码,将Cards模型对象作为参数传递
itemBuilder: (BuildContext context, int index) {
var item = new Cards.fromJson(cardList[index]);
return CardItem(item);
},
staggeredTileBuilder: (index) => StaggeredTile.fit(2),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),
);
}
}
}
这部分主要从数据模型取出数据,编写每一个子项的页面布局。
import 'package:flutter/material.dart';
import 'package:oblivion/model/CardModel.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:transparent_image/transparent_image.dart';
class CardItem extends StatefulWidget {
CardItem(this.item);
final Cards item;
@override
_CardItemState createState() {
return _CardItemState();
}
}
class _CardItemState extends State<CardItem> {
_CardItemState();
@override
Widget build(BuildContext context) {
return Card(
child: InkWell(
onTap: (){
// 跳转到商品详情
print('点击了一件商品');
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// 图片
Container(
width: double.infinity,
color: Colors.grey,
child:FadeInImage.assetNetwork(
placeholder: 'assets/images/loader.gif',
image: widget.item.img,//这里是网络图片
fit: BoxFit.fill,
),
),
// 描述
Container(
padding: EdgeInsets.fromLTRB(5, 5, 5, 0),
child: Text(widget.item.des,
maxLines: 2,
overflow: TextOverflow.ellipsis,
)
),
Container(
height: ScreenUtil().setHeight(80),
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
child: Align(
alignment: Alignment.bottomLeft,
heightFactor: 2,
widthFactor: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// 价钱和想要人数
Text("¥${widget.item.price.toString()}",style:TextStyle(color:Colors.pink)),
Text("${widget.item.want.toString()}人想要",style:TextStyle(fontSize: 10)),
],
),
),
),
Padding(
padding: EdgeInsets.all(1.0),
child: new Divider()
),
Container(
height: ScreenUtil().setHeight(160),
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
child: Align(
alignment: Alignment.bottomLeft,
heightFactor: 2,
widthFactor: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// 价钱和想要
Padding(
padding: EdgeInsets.only(top: 6),
child: Column(
children: <Widget>[
Image.network(
widget.item.img,
fit: BoxFit.fill,
height: ScreenUtil().setHeight(110),
width: ScreenUtil().setWidth(80),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(6, 0, 0, 0),
child: Center(
child: Text(widget.item.username,style:TextStyle(color:Colors.black)),
),
)
],
),
),
),
],
),
)
);
}
}
class CardModel {
List<Cards> _cards;
CardModel({List<Cards> cards}) {
this._cards = cards;
}
List<Cards> get cards => _cards;
set cards(List<Cards> cards) => _cards = cards;
CardModel.fromJson(Map<String, dynamic> json) {
if (json['cards'] != null) {
_cards = new List<Cards>();
json['cards'].forEach((v) {
_cards.add(new Cards.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this._cards != null) {
data['cards'] = this._cards.map((v) => v.toJson()).toList();
}
return data;
}
}
class Cards {
String _img;
String _des;
int _price;
int _want;
String _username;
Cards({String img, String des, int price, int want, String username}) {
this._img = img;
this._des = des;
this._price = price;
this._want = want;
this._username = username;
}
String get img => _img;
set img(String img) => _img = img;
String get des => _des;
set des(String des) => _des = des;
int get price => _price;
set price(int price) => _price = price;
int get want => _want;
set want(int want) => _want = want;
String get username => _username;
set username(String username) => _username = username;
Cards.fromJson(Map<String, dynamic> json) {
_img = json['img'];
_des = json['des'];
_price = json['price'];
_want = json['want'];
_username = json['username'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['img'] = this._img;
data['des'] = this._des;
data['price'] = this._price;
data['want'] = this._want;
data['username'] = this._username;
return data;
}
}
JSON格式
{
"cards": [{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_1.jpg",
"des": "美国短毛猫是原产于美国的一种猫,其祖先为欧洲早期移民带到北美的猫种,并与英国短毛猫和欧洲短毛猫同类。美国短毛猫的身体匀称、有力量,且活泼温顺。幼年短毛猫圆头圆脑,软绵绵的手感和灵活的四肢很是讨人喜欢",
"price": 111.00,
"want": 122,
"username": "美羊羊"
},
{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_2.jpg",
"des": "布偶猫是猫中较大、较重的一种。它的头呈V形,眼大而圆,被毛丰厚,四肢粗大,尾长,身体柔软,多为三色或双色猫。",
"price": 111.00,
"want": 1000,
"username": "小窝"
},
{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_3.jpg",
"des": "布偶猫是猫中较大、较重的一种。它的头呈V形,眼大而圆,被毛丰厚,四肢粗大,尾长,身体柔软,多为三色或双色猫。",
"price": 111.00,
"want": 122,
"username": "海绵宝宝"
},
{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_4.jpg",
"des": "美国短毛猫是原产于美国的一种猫,其祖先为欧洲早期移民带到北美的猫种,并与英国短毛猫和欧洲短毛猫同类。美国短毛猫的身体匀称、有力量,且活泼温顺。幼年短毛猫圆头圆脑,软绵绵的手感和灵活的四肢很是讨人喜欢",
"price": 111.00,
"want": 122,
"username": "流传风"
},
{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_5.jpg",
"des": "美国短毛猫是原产于美国的一种猫,其祖先为欧洲早期移民带到北美的猫种,并与英国短毛猫和欧洲短毛猫同类。美国短毛猫的身体匀称、有力量,且活泼温顺。幼年短毛猫圆头圆脑,软绵绵的手感和灵活的四肢很是讨人喜欢",
"price": 111.00,
"want": 122,
"username": "大发明家"
},
{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_6.jpg",
"des": "美国短毛猫是原产于美国的一种猫,其祖先为欧洲早期移民带到北美的猫种,并与英国短毛猫和欧洲短毛猫同类。美国短毛猫的身体匀称、有力量,且活泼温顺。幼年短毛猫圆头圆脑,软绵绵的手感和灵活的四肢很是讨人喜欢",
"price": 111.00,
"want": 122,
"username": "冰封凤凰"
},
{
"img": "http://scrutiny.geekadpt.cn/v1/images/card_1.jpg",
"des": "美国短毛猫是原产于美国的一种猫,其祖先为欧洲早期移民带到北美的猫种,并与英国短毛猫和欧洲短毛猫同类。美国短毛猫的身体匀称、有力量,且活泼温顺。幼年短毛猫圆头圆脑,软绵绵的手感和灵活的四肢很是讨人喜欢",
"price": 111.00,
"want": 122,
"username": "宇宙星神"
}
]
}