Flutter 瀑布流效果【转载】

2,282 阅读3分钟

前言 :

各位同学大家好, 瀑布流列表显示效果相信在坐的同学中做过原生安卓 和iOS的同学都有实现过吧。 原生的实现方式网上都很多开源例子甚至是开源库 ,我就不展开讲了。今天我主要给大家介绍下flutter中瀑布流如何实现的 ,废话不多说我们正式开始 。

效果如图:

image.png

准备工作 :

安装flutter环境 如果只是跑安卓设备, win系统就行了。要是同时运行安卓和iOS 就需要mac电脑了 配置环境变量这边就不展开讲了。

需要用到的三方库:

flutter_staggered_grid_view:

cached_network_image: ^2.2.0+1

flutter sdk 版本 如图:

image.png

首先请把 这个两个三方库

flutter_staggered_grid_view:\
cached_network_image: ^2.2.0+1\

拷贝到项目的 pubspec.yaml 中 如图:

image.png

然后在控制台输入 flutter pub get 命令进行下载以来即可

image.png

这边主要是用到三方库中的 StaggeredGridView 组件,在flutter原生api的里面提供的lisview 和gridview 并没有提供瀑布流的实现效果 ,所以我们用到这个三方库组件 StaggeredGridView 来实现。

1、使用StaggeredGridView

大体就两种方式,一种是传入List另一种是用itemBuilder创建item,默认提供了一下几种方法创建,根据自己的需要选择即可。

StaggeredGridView()\
StaggeredGridView.builder()\
StaggeredGridView.custom()\
StaggeredGridView.count()\
StaggeredGridView.countBuilder()\
StaggeredGridView.extent()\
StaggeredGridView.extentBuilder()\

这里我们选择使用countBuilder这种模式

body: new StaggeredGridView.countBuilder(\
padding: const EdgeInsets.all(8.0),\
crossAxisCount: 4,\
itemCount: imgList.length,\
itemBuilder: (context, i) {\
return itemWidget(i);\
},\
// staggeredTileBuilder: (index) => new StaggeredTile.fit(2),\
staggeredTileBuilder: (int index) =>\
new StaggeredTile.count(2, index == 0 ? 2.5 : 3), //\
mainAxisSpacing: 8.0,\
crossAxisSpacing: 8.0,\
),\

staggeredTileBuilder则决定每个item的宽高,核心逻辑。

staggeredTileBuilder: (int index) => new StaggeredTile.count(2, index == 0 ? 2.5 : 3),\

我这里设置第一张主轴为2.5其他的为3这样就形成了一个简单的瀑布流样式

具体效果如图:

image.png 具体完整代码实现如下:

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';\
import 'full_screenimagepage.dart';\
/**\
* 创建人:xuqing\
* 创建时间:2020年6月26日04:00:19\
* 类说明:瀑布流主页逻辑实现\
*\
*/\
void main() => runApp(MyApp());\
class MyApp extends StatelessWidget {\
@override\
Widget build(BuildContext context) {\
return MaterialApp(\
title: 'Flutter Demo',\
theme: ThemeData(\
primarySwatch: Colors.blue,\
),\
home: MyHomePage(title: '瀑布流'),\
);\
}\
}\
\
class MyHomePage extends StatefulWidget {\
MyHomePage({Key key, this.title}) : super(key: key);\
final String title;\
\
@override\
_MyHomePageState createState() => _MyHomePageState();\
}\
\
class _MyHomePageState extends State<MyHomePage> {\
List imgList = [\
"http://yanxuan.nosdn.127.net/65091eebc48899298171c2eb6696fe27.jpg",\
"http://yanxuan.nosdn.127.net/8b30eeb17c831eba08b97bdcb4c46a8e.png",\
"http://yanxuan.nosdn.127.net/a196b367f23ccfd8205b6da647c62b84.png",\
"http://yanxuan.nosdn.127.net/149dfa87a7324e184c5526ead81de9ad.png",\
"http://yanxuan.nosdn.127.net/88dc5d80c6f84102f003ecd69c86e1cf.png",\
"http://yanxuan.nosdn.127.net/8b9328496990357033d4259fda250679.png",\
"http://yanxuan.nosdn.127.net/c39d54c06a71b4b61b6092a0d31f2335.png",\
"http://yanxuan.nosdn.127.net/ee92704f3b8323905b51fc647823e6e5.png",\
"http://yanxuan.nosdn.127.net/e564410546a11ddceb5a82bfce8da43d.png",\
"http://yanxuan.nosdn.127.net/56f4b4753392d27c0c2ccceeb579ed6f.png",\
"http://yanxuan.nosdn.127.net/6a54ccc389afb2459b163245bbb2c978.png",\
'https://picsum.photos/id/101/548/338',\
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1569842561051&di=45c181341a1420ca1a9543ca67b89086&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201504%2F17%2F20150417212547_VMvrj.jpeg',\
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1570437233&di=9239dbc3237f1d21955b50e34d76c9d5&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201508%2F30%2F20150830095308_UAQEi.thumb.700_0.jpeg'\
];\
\
@override\
Widget build(BuildContext context) {\
return Scaffold(\
appBar: AppBar(\
title: Text(widget.title),\
),\
body: new StaggeredGridView.countBuilder(\
padding: const EdgeInsets.all(8.0),\
crossAxisCount: 4,\
itemCount: imgList.length,\
itemBuilder: (context, i) {\
return itemWidget(i);\
},\
// staggeredTileBuilder: (index) => new StaggeredTile.fit(2),\
staggeredTileBuilder: (int index) =>\
new StaggeredTile.count(2, index == 0 ? 2.5 : 3), //\
mainAxisSpacing: 8.0,\
crossAxisSpacing: 8.0,\
),\
);\
}\
Widget itemWidget(int index){\
String imgPath = imgList[index];\
return new Material(\
elevation: 8.0,\
borderRadius: new BorderRadius.all(\
new Radius.circular(8.0),\
),\
child: new InkWell(\
onTap: () {\
Navigator.push(\
context,\
new MaterialPageRoute(\
builder: (context) {\
return new FullScreenImagePage(imageurl: imgPath);\
},\
),\
);\
},\
child: new Hero(\
tag: imgPath,\
child: CachedNetworkImage(\
imageUrl: imgPath,\
fit: BoxFit.fitWidth,\
/* placeholder: (context, url) =>\
Image.asset('assets/wallfy.png'),*/\
),\
),\
),\
);\
}\
}\

最后在item的点击事件里面添加了点击跳转到新开页面widget显示所点击的图片

点击核心代码

onTap: () {\
Navigator.push(\
context,\
new MaterialPageRoute(\
builder: (context) {\
return new FullScreenImagePage(imageurl: imgPath);\
},\
),\
);\
},\

通过构造方法把选中的图片的url传到 FullScreenImagePage 类中, 然后在Img.network中传入即可实现

跳转新页面核心代码 :

import 'package:flutter/material.dart';\
/**\
*\
* 创建人:xuqing\
* 创建时间:2020年6月26日03:03:05\
* 类说明:图片详情页面\
*\
*/\
class FullScreenImagePage extends StatefulWidget {\
final String imageurl;\
FullScreenImagePage({Key key,this.imageurl}) : super(key: key);\
\
@override\
_FullScreenImagePageState createState() {\
return _FullScreenImagePageState();\
}\
}\
class _FullScreenImagePageState extends State<FullScreenImagePage> {\
@override\
void initState() {\
super.initState();\
}\
@override\
void dispose() {\
super.dispose();\
}\
@override\
Widget build(BuildContext context) {\
// TODO: implement build\
return Scaffold(\
appBar: AppBar(\
title: Text("图片详情页面"),\
centerTitle: true,\
),\
body:Container(\
margin: EdgeInsets.all(20.0),\
child: Image.network(widget.imageurl, fit: BoxFit.fitWidth,),\
),\
);\
}\
}\

最后总结 :

相交于安卓原生来说 flutter提供了很好用很方便的三方库组件flutter_staggered_grid_view, 来实现就简单方便很多 也节省大家的开发时间和提供开发效率。flutter_staggered_grid_view 用法用起来和gridview差别不大,个别特殊属性大家需要注意 ,当然这种瀑布流列表布局也可以自己封装gridview来实现 有兴趣的同学可以私下研究下。这里就不过多讲了 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。

原文链接: blog.51cto.com/u_12300179/…