需求:
相信android和ios的瀑布流效果大家都试过,网上有很多实现方法和开源库,今天我来为大家介绍一下如何在Flutter中实现瀑布流,整理一下方便以后学习,顺便分享给大家。
一、生成二维码
1、导入依赖
在 pubspec.yaml 中 dependencies 节点下添加:
# 瀑布流插件
flutter_staggered_grid_view: ^0.3.3
# 网络缓存图片
cached_network_image : ^0.6.2
2、引入代码
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
3、创建方式
StaggeredGridView一共有6中创建方式:
StaggeredGridView.count()
StaggeredGridView.countBuilder()
StaggeredGridView.builder()
StaggeredGridView.custom()
StaggeredGridView.extent()
StaggeredGridView.extentBuilder()
StaggeredGridView.count():创建了一个纵轴方向固定Tile个数的布局,适合子Widget个数比较少的情况,使用List来设置。
StaggeredGridView.countBuilder():和StaggeredGridView.count()差不多,区别在于适合子Widget数量比较多,需要动态创建的情况。
StaggeredGridView.extent():创建了一个在纵轴方法指定Tile个数的最大值的布局,适合子Widget个数比较少的情况,使用List来设置。
StaggeredGridView.extentBuilder():和StaggeredGridView.extent()差不多,区别在于适合子Widget数量比较多,需要动态创建的情况。
StaggeredGridView.builder()和StaggeredGridView.custom()更高级也更灵活。
这里我们选择使用countBuilder
body: StaggeredGridView.countBuilder(
crossAxisCount: 4, //横轴单元格数量
itemCount: 20, //元素数量
itemBuilder: (context,i){
return new Material(
elevation: 8.0,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
child: new CachedNetworkImage(
imageUrl: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.yuntouxiang.com%2Fuploads%2F20130521%2F21-022304_646.jpg&refer=http%3A%2F%2Fimg1.yuntouxiang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1613615452&t=590bdef8fdbfb5c972066acbeca6543d",
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fitHeight,
),
),
),
),
);
},
staggeredTileBuilder: (index){
return StaggeredTile.count(2, index.isEven ? 2 : 1); //第一个参数是横轴所占的单元数,第二个参数是主轴所占的单元数
},
padding: EdgeInsets.all(8),
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
),
itemBuilder是每个瀑布流的item,imageUrl可以改成数组,这样就可以显示不同的图片。crossAxisCount是指横轴总宽度被分为4份,总计四个单元格,itemCount指总元素数量
staggeredTileBuilder: (index){
return StaggeredTile.count(2, index.isEven ? 2 : 1); //第一个参数是横轴所占的单元数,第二个参数是主轴所占的单元数
},
我设置每个item的宽度占2个单元格,这样就是一行两个,左右平分空间,高度偶数item为2,奇数为1,这个如果每个item高度都有不同高度的话,可以将item的高度用数组导入。
具体效果:
完整代码如下所示:
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
class Staggered extends StatefulWidget {
@override
_StaggeredState createState() => _StaggeredState();
}
class _StaggeredState extends State<Staggered> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("瀑布流"),
),
body: StaggeredGridView.countBuilder(
crossAxisCount: 4, //横轴单元格数量
itemCount: 20, //元素数量
itemBuilder: (context,i){
return new Material(
elevation: 8.0,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
child: new CachedNetworkImage(
imageUrl: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.yuntouxiang.com%2Fuploads%2F20130521%2F21-022304_646.jpg&refer=http%3A%2F%2Fimg1.yuntouxiang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1613615452&t=590bdef8fdbfb5c972066acbeca6543d",
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fitHeight,
),
),
),
),
);
},
staggeredTileBuilder: (index){
return StaggeredTile.count(2, index.isEven ? 2 : 1); //第一个参数是横轴所占的单元数,第二个参数是主轴所占的单元数
},
padding: EdgeInsets.all(8),
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
),
);
}
}