Flutter 瀑布流效果

前言 :

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

效果如图:

QQ截图20200626040819.png

准备工作 :

安装flutter环境 如果只是跑安卓设备, win系统就行了。要是同时运行安卓和iOS 就需要mac电脑了 配置环境变量这边就不展开讲了,大家可以看我之前的文章。

需要用到的三方库:

flutter_staggered_grid_view:
cached_network_image: ^2.2.0+1

flutter sdk 版本 如图:

QQ截图20200626042048.png

首先请把 这个两个三方库

 flutter_staggered_grid_view:
 cached_network_image: ^2.2.0+1

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


QQ截图20200626042144.png

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


QQ截图20200626042416.png

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

1、使用StaggeredGridView

大体就两种方式,一种是传入List<Widget>另一种是用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这样就形成了一个简单的瀑布流样式

具体效果如图:

QQ截图20200626040819.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来实现 有兴趣的同学可以私下研究下。这里就不过多讲了 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。如果觉得文章还不错 ,麻烦给关注和star
项目地址:https://github.com/xq19930522/pubuliu

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335