Flutter achieves waterfall effect (GridView component does not have a fixed height)

introduction

The waterfall flow layout is implemented in the Flutter APP to display product information. Effect picture:

Insert picture description here

安装 flutter_staggered_grid_view

The grid layout component that comes with Flutter fixes the height of each sub-component, which cannot meet our needs. GridView component: as shown in the figure below:

Insert picture description here
To achieve the waterfall flow effect, you need to use a third-party package: flutter_staggered_grid_view

Use flutter_staggered_grid_view in layout

In order to facilitate code reading and expansion, reduce nesting and clarify business logic (Wen Zou Zou's theory...), in fact, the parent page of the GridView component and the layout of its children are written in two files.

card_page.dart parent page

This mainly instantiates the encapsulated Dio class to request product data and write parent page layout.

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

square_card_item.dart sub-component

This part mainly fetches data from the data model and writes the page layout of each sub-item.

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)),
                        ),
                      )

                    ],
                  ),
                ),
              ),
            ],
          ),
        )
    );
  }
}

Card data model

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 format

{
    
    
	"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": "宇宙星神"
		}
	]
}

Guess you like

Origin blog.csdn.net/geeksoarsky/article/details/106567284