• Flutter利用GridView创建网格布局实现优美布局


    请添加图片描述

    简介

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

    使用详解

    以下是关于如何使用 GridView 控件的详细讲解:

    导入依赖项

    在你的 Flutter 项目中,首先确保已经导入了 flutter/material.dart 包,因为 GridView 是 material 包的一部分,然后你可以使用以下代码创建一个简单的 GridView:

    import 'package:flutter/material.dart';
    
    • 1

    创建一个基本的 GridView

    下面是一个基本的 GridView 示例,它创建了一个包含一组简单文本小部件的网格:

    GridView(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2, // 列数
        mainAxisSpacing: 10.0, // 垂直间距
        crossAxisSpacing: 10.0, // 水平间距
      ),
      children: <Widget>[
        Container(
          color: Colors.red,
          child: Center(child: Text('Item 1')),
        ),
        Container(
          color: Colors.green,
          child: Center(child: Text('Item 2')),
        ),
        Container(
          color: Colors.blue,
          child: Center(child: Text('Item 3')),
        ),
        // 可以继续添加更多的子小部件
      ],
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这个示例中,我们创建了一个包含三个列的网格(crossAxisCount: 2)。每个网格项都由一个带有不同背景颜色的 Container 包装,并且包含一个居中对齐的文本小部件。

    一些参数说明

    SliverGridDelegateWithFixedCrossAxisCount
    gridDelegate 属性是 GridView 的一个关键部分,它用于定义网格的布局方式。在上面的示例中,我们使用了 SliverGridDelegateWithFixedCrossAxisCount,它采用以下参数:

    crossAxisCount:指定了列数。
    mainAxisSpacing:指定了主轴(通常是垂直轴)上的间距。
    crossAxisSpacing:指定了交叉轴(通常是水平轴)上的间距。
    使用 builder 构建动态网格
    如果你有一个大数据源,并且不想一次性加载所有数据,你可以使用 GridView.builder,它会根据需要生成网格项。以下是一个示例:

    GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 10.0,
        crossAxisSpacing: 10.0,
      ),
      itemCount: yourData.length, // 数据源的长度
      itemBuilder: (BuildContext context, int index) {
        return Container(
          color: Colors.blue,
          child: Center(child: Text('Item $index')),
        );
      },
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这个示例中,itemBuilder 函数会根据索引值生成每个网格项。你可以根据实际需求从 yourData 数据源中获取数据。

    使用GridView.count来构造

    GridView.count(
                  crossAxisCount: 4,
                  children: List.generate(snapshot.data?.length as int, (index) {
                    return Center(
                      child: Padding(
                        padding: const EdgeInsets.all(6.0),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            GestureDetector(
                              onTap: () {
                                print('Button $index is pressed,${snapshot.data?[index].sptime},${snapshot.data?[index].cycle},${snapshot.data?[index].retime}');
                                // 按钮点击事件
                                AppRouter.router.navigateTo(
                                  context,
                                  '/DoSportsPage/${snapshot.data?[index].sptime}/${snapshot.data?[index].cycle}/${snapshot.data?[index].retime}',
                                  transition: TransitionType.fadeIn,
                                );
                                // Navigator.of(context).pop();
                                // Navigator.of(context).push(MaterialPageRoute(builder: (context) => const SportsShow()));
                              },
                              //long time press button to delete data
                              onLongPress: ( ) {
                                print('Button $index is longpressed id= ${snapshot.data?[index].id}');
                                DatabaseHelper.dbhelper.delete(snapshot.data?[index].id);
                                setState(() {
                                  //show again
                                });
                              },
                              child: CircleAvatar(
                                child: Text(snapshot.data?[index].title.substring(0, 1)),
                                // radius: 30,
                                // backgroundImage: AssetImage('assets/touxiang.jpg'),
                                // backgroundColor: Colors.white,
                              ),
                            ),
                            const SizedBox(height: 8),
                            Text(
                              snapshot.data![index].title,
                              style: const TextStyle(fontSize: 12),
                            ),
                          ],
                        ),
                      ),
                    );
                  }),
                );
              } else {
                return const CircularProgressIndicator();
              }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    这段代码是使用 GridView.count 构建一个网格布局,其中 crossAxisCount 属性定义了网格的列数,而 children 属性用于指定网格中的子小部件列表。

    GridView.count: 这是一个 GridView 的构造函数,用于创建一个具有固定列数的网格布局。

    crossAxisCount: 这是 GridView.count 构造函数的一个参数,它指定了网格的列数。在你的示例中,crossAxisCount 设置为 4,表示该网格将包含四列。

    children: 这是一个包含要在网格中显示的子小部件的列表。在你的示例中,它使用 List.generate 函数生成了一个包含 snapshot.data?.length 个元素的列表。snapshot.data?.length 是一个可能为空的数据长度,因此在此处使用 ?. 运算符以避免出现空指针异常。

    List.generate 函数接受两个参数:

    第一个参数是要生成的列表的长度,这里是 snapshot.data?.length。

    第二个参数是一个回调函数,用于生成列表中每个元素的内容。在你的示例中,回调函数 (index) 生成了网格中每个元素的内容。

    所以,这段代码的作用是创建一个包含固定列数(4列)的网格,其中每个格子的内容由 List.generate 函数生成,数量等于 snapshot.data?.length。通常,snapshot.data 包含从数据源检索到的数据,而这段代码将这些数据以网格的形式进行展示。

    其他控制

    在 Flutter 中,GridView 提供了各种属性和参数,以便你可以配置滚动方向、内容填充以及滚动控制。以下是一些常用的属性和参数:

    滚动方向(scrollDirection):
    使用 scrollDirection 属性可以设置 GridView 的滚动方向。默认情况下,它是垂直方向的,但你可以将其设置为水平方向。

    GridView(
      scrollDirection: Axis.horizontal, // 设置为水平滚动
      // 其他属性...
    )
    
    • 1
    • 2
    • 3
    • 4

    内容填充(padding):
    使用 padding 属性可以设置 GridView 内容的内边距。你可以在内边距中定义空白区域,以便在网格周围留出一些空间。

    GridView(
      padding: EdgeInsets.all(16.0), // 设置内边距为16.0
      // 其他属性...
    )
    
    • 1
    • 2
    • 3
    • 4

    滚动控制(controller):
    你可以使用 controller 属性来自定义滚动控制器,以实现更高级的滚动控制功能。例如,你可以创建一个 ScrollController 并将其传递给 GridView,以便监听滚动位置、滚动到特定位置等。

    ScrollController _controller = ScrollController();
    
    GridView(
      controller: _controller,
      // 其他属性...
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这样,你可以使用 _controller 对象来执行滚动操作,例如:

    滚动到特定位置:_controller.jumpTo(offset) 或 _controller.animateTo(offset, duration: Duration(milliseconds: 500), curve: Curves.ease)

    监听滚动位置:可以添加监听器 _controller.addListener(() { /* 处理滚动位置的变化 */ })

    这些属性和参数使你能够根据需求对 GridView 进行自定义和控制,以创建不同类型的滚动网格布局。

    总结

    GridView 持许多其他配置选项,如滚动方向、内容填充、滚动控制等。你可以根据你的应用需求进行进一步的定制。总的来说,GridView 是一个非常灵活且强大的小部件,可用于创建各种网格布局。


    结束语
    Flutter是一个由Google开发的开源UI工具包,它可以让您在不同平台上创建高质量、美观的应用程序,而无需编写大量平台特定的代码。我将学习和深入研究Flutter的方方面面。从基础知识到高级技巧,从UI设计到性能优化,欢饮关注一起讨论学习,共同进入Flutter的精彩世界!
  • 相关阅读:
    element-plus 导入导出
    猿创征文 | Java知识【数组上篇】
    评价——层次分析
    机器学习笔记之隐马尔可夫模型(四)求值问题——后向算法(Backward Algorithm)
    Java Integer bitCount()方法具有什么功能呢?
    GET清求 不能传 @RequestBody 吗, (不支持POST请求方法,支持以下GET)
    P8193 [USACO22FEB] 高维前缀和
    联想Y9000P-2022款踩坑指南 加装固态和内存 win10系统安装
    聚观早报|歌尔股份辟谣被苹果砍单;扎克伯格承认因失误裁员
    商业园区的万能管理法,还怪高级的咧!
  • 原文地址:https://blog.csdn.net/yikezhuixun/article/details/134260969