Flutter完全开发手册
  • Flutter 页面布局 GridView网格布局

    GridView是 Flutter 中用于创建网格布局的强大小部件。它允许你在行和列中排列子小部件,非常适合显示大量项目,例如图像、文本、卡片等

    如下图所示可见,GridView网格布局在app中的使用频率其实非常高,所以接下来就让我们来看看在Flutter中如何使用吧~

    Flutter页面布局GridView网格布局

    初识GridView

    GridView一共有5个构造函数:GridView,GridView.builder,GridView.count,GridView.extent和GridView.custom。但是不用慌,因为可以说其实掌握其默认构造函数就都会了。

    GridView 提供了几种构造函数来创建不同类型的网格布局:

    1、GridView:最通用的构造函数,完全自定义网格布局。

    2、GridView.builder:按需构建网格项,适用于具有大量(或无限)网格项的动态内容。

    3、GridView.count:指定网格中的列数,适用于具有固定数量列的网格。

    4、GridView.extent:指定网格中最大交叉轴范围(例如,最大列宽),适用于需要控制列宽的网格。

    5、GridView.custom:这个构造函数提供了最高级别的自定义能力,允许使用自定义的SliverGridDelegate和SliverChildDelegate。

    主要介绍两种

    1、可以通过 GridView.count 实现网格布局

    2、通过 GridView.builder 实现网格布局

    GridView是一个可滚动的view,也就是ScrollView,事实上GridView继承自BoxScrollView:

    GridView常用属性:

    属性说明
    scrollDirection滚动方向
    reverse组件反向排序
    controller滚动控制(滚动监听)
    primary如果内容不足,则用户无法滚动 而如果[primary]为true,它们总是可以尝试滚动。
    physics

    滑动类型设置

    AlwaysScrollableScrollPhysics() 总是可以滑动
    NeverScrollableScrollPhysics禁止滚动
    BouncingScrollPhysics 内容超过一屏 上拉有回弹效果
    ClampingScrollPhysics 包裹内容 不会有回弹

    shrinkWrap默认false   内容适配
    padding内边距
    crossAxisCount列 数量
    mainAxisSpacing垂直子 Widget 之间间距
    crossAxisSpacing水平子 Widget 之间间距
    childAspectRatio子 Widget 宽高比例
    addAutomaticKeepAlives默认true
    addRepaintBoundaries默认true
    addSemanticIndexes默认true
    cacheExtent设置预加载的区域
    children子元素
    semanticChildCount将提供语义信息的子代数量
    dragStartBehavior 
    GridView.builder独有属性 
    gridDelegate一个控制 GridView 中子项布局的委托。
    itemBuilder遍历数返回Widget
    itemCount子控件数量

    GridView.count 实现网格布局

    ● GridView.count 接收下面的命名参数:

    ● crossAxisCount 是必传的,用来控制横轴上子项的个数

    ● crossAxisSpacing 用来指定横轴上两列的宽度间隙

    ● mainAxisSpacing 用来指定纵轴上两行的高度间隙

    ● childAspectRatio宽高比

    
    //网格布局演示
    class GridView_test extends StatelessWidget{
      List _initlistdata(){
        List tmplist=[];    //创建一个存储widget的列表
        for(var i=0; i<list.length; i++){    //list为接收到的数据,在头文件引入
          tmplist.add(Container(
            alignment: Alignment.bottomRight,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.red,width: 2),   //设置边框
               //设置图片填充方式
            ),
            child:Column(
              children: [
                Image(image: NetworkImage("${list[i]["cover"]}")), //设置显示图片
                const SizedBox(height: 10,),
                Text("${list[i]["name"]}",)//设置文字
              ],
            ),
          ),
          );
        }
        return tmplist;
      }
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return GridView.count(
            crossAxisCount: 3,  //设置一行的个数
            crossAxisSpacing:10,  //设置列间距
            mainAxisSpacing: 10, //设置行间距
          children:_initlistdata()
        );
      }
    }
    

    Flutter页面布局GridView网格布局

    GridView.builder实现动态列表

    当子widget较多时可以使用该方法来动态创建子widget,在使用GridView.builder时有两个比传入参数gridDelegate与itemBuilder

    ● gridDelegate是SliverGridDelegate类型,主要是用来控制GridView的子Widget的样式

    ● itemBuilder方法接收context和index两个参数,返回widget即可

    
    //网格布局演示二
    class Gridview_test2 extends StatelessWidget{
      Widget _initlistdata(context,index){
        return Container(
            alignment: Alignment.bottomRight,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.red,width: 2),   //设置边框
              //设置图片填充方式
            ),
            child:Column(
              children: [
                Image(image: NetworkImage("${list[index]["cover"]}")), //设置显示图片
                const SizedBox(height: 10,),
                Text("${list[index]["name"]}",)//设置文字
              ],
            ),
          );
        }
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return GridView.builder(
            itemCount: list.length,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2
        ), itemBuilder: _initlistdata);
      }
    }