首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter GridView 网格控件

Flutter GridView 网格控件

作者头像
毛大姑娘
发布2020-09-10 15:47:35
1.5K0
发布2020-09-10 15:47:35
举报
文章被收录于专栏:向全栈出发向全栈出发

在项目中,有时候会有诸如“日历”展示之类的需求,此时单列表ListView控件已经无法满足我们的需要。GridView就是为了满足这样的“二维数组”排列而存在的。

1、默认构造函数

GridView({
  //与ListView相同的参数  
  Axis scrollDirection = Axis.vertical,
  bool reverse = false,
  ScrollController controller,
  bool primary,
  ScrollPhysics physics,
  bool shrinkWrap = false,
  EdgeInsetsGeometry padding,
  bool addAutomaticKeepAlives = true,
  bool addRepaintBoundaries = true,
  double cacheExtent,
  //GridView特有属性
  @required SliverGridDelegate gridDelegate, //控制子widget layout的委托
  List<Widget> children = const <Widget>[],
})

GridView的大部分参数与ListView是一样的,请参见系列文章《Flutter ListView 列表控件》。

我们需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout)。

SliverGridDelegate是一个抽象类,定义了GridView Layout相关接口。Flutter中提供了两个子类:SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent,我们可以直接使用。

2、SliverGridDelegateWithFixedCrossAxisCount

属性值

含义

crossAxisCount

决定有网格有多少列数据

mainAxisSpacing

主轴方向item之间的间隙

crossAxisSpacing

非主轴方向item之间的间隙

childAspectRatio

非主轴方向的item内容与主轴方向的内容宽高比默认=1.0(即1:1展示)

@required this.crossAxisCount,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.childAspectRatio = 1.0,
2.1、举例说明:

假设需要实现一个3列的网格(只需要固定列,行数可根据数据多少自动调节),主轴方向item间隙为20像素,非主轴方向的item间隙为10像素,非主轴方向的内容是主轴方向内容的2倍容量。我们可以这样实现:

      body: GridView(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          mainAxisSpacing: 20,
          crossAxisSpacing: 10,
          childAspectRatio: 2,
        ),
        children: <Widget>[
          Container(
            color: Colors.green,
            child: Icon(Icons.ac_unit),
          ),
          //……此处省略7个Icon代码
          Container(
            color: Colors.green,
            child: Icon(Icons.accessible_forward),
          ),
        ],
      ),

Icon外面包裹Container控件是为了设置背景颜色,让效果更直观。

效果如下:

3、SliverGridDelegateWithMaxCrossAxisExtent

属性值

含义

maxCrossAxisExtent

决定每一列的item占用多少像素

mainAxisSpacing

主轴方向item之间的间隙

crossAxisSpacing

非主轴方向item之间的间隙

childAspectRatio

非主轴方向的item内容与主轴方向的内容宽高比默认=1.0(即1:1展示)

    @required this.maxCrossAxisExtent,
    this.mainAxisSpacing = 0.0,
    this.crossAxisSpacing = 0.0,
    this.childAspectRatio = 1.0,

mainAxisSpacing、crossAxisSpacing、childAspectRatio三个参数与SliverGridDelegateWithFixedCrossAxisCount相同,这里我们主要理解maxCrossAxisExtent的用法。

  • maxCrossAxisExtent

此参数表示每一列的item占用多少像素的宽度。假设非主轴(横轴)的总像素是500,那么mainAxisSpacing = 100表示每行可展示5列(前提是设置item间隙)。因此,可以通过控制mainAxisSpacing的值来动态控制网格布局的列数。

3.1、举例说明:

假设将maxCrossAxisExtent设为80,主轴方向item间隙为10像素,非主轴方向的item间隙为10像素,非主轴方向的内容是主轴方向内容的2倍容量。我们可以这样实现:

      body: GridView(
        gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
          maxCrossAxisExtent: 80,
          mainAxisSpacing: 10,
          crossAxisSpacing: 10,
          childAspectRatio: 2,
        ),
        children: <Widget>[
          Container(
            color: Colors.green,
            child: Icon(Icons.ac_unit),
          ),
          //……此处省略7个Icon代码
          Container(
            color: Colors.green,
            child: Icon(Icons.accessible_forward),
          ),
        ],
      ),

效果如下:

可以看出网格布局变成了5列,通过计算80*5+10*4=440px得出使用宽度为440像素,剩下60像素不足以再多出一列的宽度,所以最多只能生成5列数据。

4、GridView.extent

GridView.extentSliverGridDelegateWithMaxCrossAxisExtent的另一种代码表现形式(大概是因为名字太长了),它们具有相同的功能。

用法:

      body: GridView.extent(
        maxCrossAxisExtent: 80,
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
        childAspectRatio: 2,

5、GridView.builder

以上GridView都需要事先排列好所有的item布局(widget),这就相当于将数据提前写死了,不方便动态拓展,也不适合数据过多的情况。当子widget比较多时,我们可以通过GridView.builder来动态创建子widget。

GridView.builder(gridDelegate: null, itemBuilder: null),

gridDelegate参数在上面已经讲过了,我们主要来看看itemBuilder如何使用。

5.1、举例说明:

设置一个网格布局,拥有50个子项目,前10个项目输出索引,拥有绿色背景,之后所有项目拥有蓝色背景。

          child: GridView.builder(
              gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 100,
                mainAxisSpacing: 10,
                crossAxisSpacing: 10,
                childAspectRatio: 2,
              ),
              itemCount: 50,
              itemBuilder: (BuildContext context, int position) {
                Widget item;
                if (position < 10) {
                  item = FlatButton.icon(
                    icon: Icon(Icons.info),
                    label: Text("" + position.toString()),
                    color: Colors.green,
                    onPressed: () {},
                  );
                } else {
                  item = Container(
                    color: Colors.blue,
                    child: Icon(
                      Icons.airplanemode_active,
                      color: Colors.white,
                    ),
                  );
                }
                return item;
              }),

注意:itemCount虽然不是必选参数,实际使用时别忘记加上,它是决定子项显示数量的关键因素。

效果如下:


6、StaggeredGridView.countBuilder 瀑布流

StaggeredGridView不是Flutter提供的GridView组件,而是专门为实现瀑布流而存在的flutter_staggered_grid_view包提供的功能。

6.1、使用步骤:
  1. 导入flutter_staggered_grid_view库。

pubspec.yaml文件中导入如下代码:

dependencies:
  # 瀑布流
  flutter_staggered_grid_view: ^0.2.7
  1. 导入包到代码文件
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
  1. 使用
        StaggeredGridView.countBuilder(
          mainAxisSpacing: 4.0,
          crossAxisSpacing: 4.0,
          crossAxisCount: 4,
          itemCount: 20,
          itemBuilder: (BuildContext context, int index) => new Container(
              color: index.isEven ? Colors.green : Colors.yellow,
              child: new Center(
                child: new CircleAvatar(
                  backgroundColor: Colors.white,
                  child: new Text('$index'),
                ),
              )),
          staggeredTileBuilder: (int index) =>
              new StaggeredTile.count(2, index.isEven ? 2 : 1),
        )

4.效果图

分析:

最主要起到瀑布流效果的是这句代码: `staggeredTileBuilder: (int index) =>

          new StaggeredTile.count(2, index.isEven ? 2 : 1),`

实际运用中需要根据实际情况对瀑布流item的高度进行调整。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年08月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、默认构造函数
  • 2、SliverGridDelegateWithFixedCrossAxisCount
    • 2.1、举例说明:
    • 3、SliverGridDelegateWithMaxCrossAxisExtent
      • 3.1、举例说明:
      • 4、GridView.extent
      • 5、GridView.builder
        • 5.1、举例说明:
        • 6、StaggeredGridView.countBuilder 瀑布流
          • 6.1、使用步骤:
            • 分析:
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档