Flutter---GridView+自定义控件

概念:GridView 是 Flutter 中用于创建网格布局的滚动组件,类似于表格但支持滚动。

GridView有四种创建方式

①GridView.count - 固定列数

②GridView.extent - 固定最大宽度

③GridView.builder - 动态创建(推荐用于大量数据)

④GridView.custom - 完全自定义

这里主要分享第一种GridView.count

效果图,如果要看滚动的效果,就把数据多复制几次

步骤:

这个项目的点击事件用到了fluttertoast,所以需要导入fluttertoast外部类。

1.在pubspec.yaml中导入依赖(注意空格的缩进)。

Dart 复制代码
dependencies:
  fluttertoast: ^8.2.2  # 检查最新版本

2.在需要的页面导入这个类

Dart 复制代码
import 'package:fluttertoast/fluttertoast.dart';

3.自定义控件

Dart 复制代码
//自定义控件
  Widget buildItem({
    required String icon, //图片1
    required String title, //文本1
    required String subtitle,//文本2
    required List<Color> colors,//颜色1
    required VoidCallback callback,//VoidCallback:无参数无返回值的函数类型
}){
    return Container(
      //容器基础样式
      height: 85,
      width: 155,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10),//圆角
          gradient: LinearGradient(//垂直渐变
            begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: colors
          ),
      ),

      //使用Material Ink InkWell 组合 点击波纹效果
      //点击效果实现
      child: Material( //提供材质
        color: Colors.transparent,
        child: Ink(//墨水效果容器
          child: InkWell(//实际产生波纹效果的组件
            borderRadius: BorderRadius.circular(10),
            onTap: callback,//点击时传入的回调函数

            //内部布局结构
            child: Padding(
              padding: const EdgeInsets.only(left: 15,top: 12.5,bottom:10,right:15),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,//子组件左对齐
                children: [
                  const Expanded(child: SizedBox()),//弹性撑开空间,Expanded会占据所有可用空间,将后面的Row推向底部
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,//两端对齐
                    children: [
                      //左侧文本列
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(title,style: const TextStyle(fontSize:18,fontWeight: FontWeight.bold),),//使用传入的文字1
                          Text(subtitle,style: const TextStyle(color: Colors.white,fontSize: 10),),//使用传入的文字2
                        ],
                      ),
                      //右侧图标
                      Image.asset(icon,width: 40,height: 40,),//使用传入的图片1
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

自定义框架的整体布局层级

Padding (内边距)

└── Column (垂直布局)

└── Expanded (弹性空间)

└── Row (水平布局)

├── Column (文本列)

│ ├── Text (主标题)

│ └── Text (副标题)

└── Image.asset (图标)

4.在UI中使用自定义控件

Dart 复制代码
return Scaffold(
      body: Center(
        child: Column(

          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Expanded(
              child: Padding(
                padding: EdgeInsets.symmetric(horizontal: 10),
                child: GridView.count(
                  crossAxisCount: 2,//固定列数
                  crossAxisSpacing: 8,//列间距
                  mainAxisSpacing: 8,//行间距
                  childAspectRatio: 1.823,//子项的宽高比

                  children: [
                    buildItem(
                      icon: "assets/images/apple.png",
                      title: "红楼梦",
                      subtitle: "作者:曹雪芹",
                      colors: const [Color(0xFF8EE6FE),Color(0xFF2BBDE7)],
                      callback: (){
                        Fluttertoast.showToast(msg: "你点击了红楼梦!!!");
                      }
                    ),

                    buildItem(
                      icon: "assets/images/banana.png",
                      title: "西游戏",
                      subtitle: "作者:吴承恩",
                      colors: const [Color(0xFFFFCC91),Color(0xFFFF8a65)],
                        callback: (){
                          Fluttertoast.showToast(msg: "你点击了西游记!!!");
                        }
                    ),

                    buildItem(
                      icon: "assets/images/cherry.png",
                      title: "水浒传",
                      subtitle: "作者:施耐庵",
                      colors: const [Color(0xFF77FA76),Color(0xFF31F0A3)],
                        callback: (){
                        print("点击事件触发");
                          Fluttertoast.showToast(
                            msg: "你点击了水浒传!!!",

                          );
                        }
                    ),

                    buildItem(
                      icon: "assets/images/mango.png",
                      title: "三国演义",
                      subtitle: "作者:罗贯中",
                      colors: const [Color(0xFFCC9EF7),Color(0xFFA973F0)],
                        callback: (){
                          Fluttertoast.showToast(msg: "你点击了三国演义!!!");
                        }
                    ),



                  ],
                ),
              ),


            ),
          ],
        ),


      ),
    );

点击效果的流程

用户点击 → InkWell检测点击 → 产生波纹动画 → 执行callback函数

代码实例

Dart 复制代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';


class HomePage extends StatefulWidget{
  const HomePage({super.key});

  @override
  State<StatefulWidget> createState() => _HomePageState();

}

class _HomePageState extends State<HomePage>{

  //自定义控件
  Widget buildItem({
    required String icon, //图片1
    required String title, //文本1
    required String subtitle,//文本2
    required List<Color> colors,//颜色1
    required VoidCallback callback,//VoidCallback:无参数无返回值的函数类型
}){
    return Container(
      //容器基础样式
      height: 85,
      width: 155,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10),//圆角
          gradient: LinearGradient(//垂直渐变
            begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: colors
          ),
      ),

      //使用Material Ink InkWell 组合 点击波纹效果
      //点击效果实现
      child: Material( //提供材质
        color: Colors.transparent,
        child: Ink(//墨水效果容器
          child: InkWell(//实际产生波纹效果的组件
            borderRadius: BorderRadius.circular(10),
            onTap: callback,//点击时传入的回调函数

            //内部布局结构
            child: Padding(
              padding: const EdgeInsets.only(left: 15,top: 12.5,bottom:10,right:15),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,//子组件左对齐
                children: [
                  const Expanded(child: SizedBox()),//弹性撑开空间,Expanded会占据所有可用空间,将后面的Row推向底部
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,//两端对齐
                    children: [
                      //左侧文本列
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(title,style: const TextStyle(fontSize:18,fontWeight: FontWeight.bold),),//使用传入的文字1
                          Text(subtitle,style: const TextStyle(color: Colors.white,fontSize: 10),),//使用传入的文字2
                        ],
                      ),
                      //右侧图标
                      Image.asset(icon,width: 40,height: 40,),//使用传入的图片1
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  //UI构建
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(

          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Expanded(
              child: Padding(
                padding: EdgeInsets.symmetric(horizontal: 10),
                child: GridView.count(
                  crossAxisCount: 2,//固定列数
                  crossAxisSpacing: 8,//列间距
                  mainAxisSpacing: 8,//行间距
                  childAspectRatio: 1.823,//子项的宽高比

                  children: [
                    buildItem(
                      icon: "assets/images/apple.png",
                      title: "红楼梦",
                      subtitle: "作者:曹雪芹",
                      colors: const [Color(0xFF8EE6FE),Color(0xFF2BBDE7)],
                      callback: (){
                        Fluttertoast.showToast(msg: "你点击了红楼梦!!!");
                      }
                    ),

                    buildItem(
                      icon: "assets/images/banana.png",
                      title: "西游戏",
                      subtitle: "作者:吴承恩",
                      colors: const [Color(0xFFFFCC91),Color(0xFFFF8a65)],
                        callback: (){
                          Fluttertoast.showToast(msg: "你点击了西游记!!!");
                        }
                    ),

                    buildItem(
                      icon: "assets/images/cherry.png",
                      title: "水浒传",
                      subtitle: "作者:施耐庵",
                      colors: const [Color(0xFF77FA76),Color(0xFF31F0A3)],
                        callback: (){
                        print("点击事件触发");
                          Fluttertoast.showToast(
                            msg: "你点击了水浒传!!!",

                          );
                        }
                    ),

                    buildItem(
                      icon: "assets/images/mango.png",
                      title: "三国演义",
                      subtitle: "作者:罗贯中",
                      colors: const [Color(0xFFCC9EF7),Color(0xFFA973F0)],
                        callback: (){
                          Fluttertoast.showToast(msg: "你点击了三国演义!!!");
                        }
                    ),



                  ],
                ),
              ),


            ),
          ],
        ),


      ),
    );
  }

}
相关推荐
LawrenceLan8 小时前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart
一豆羹9 小时前
macOS 环境下 ADB 无线调试连接失败、Protocol Fault 及端口占用的深度排查
flutter
行者969 小时前
OpenHarmony上Flutter粒子效果组件的深度适配与实践
flutter·交互·harmonyos·鸿蒙
行者9612 小时前
Flutter与OpenHarmony深度集成:数据导出组件的实战优化与性能提升
flutter·harmonyos·鸿蒙
小雨下雨的雨12 小时前
Flutter 框架跨平台鸿蒙开发 —— Row & Column 布局之轴线控制艺术
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨12 小时前
Flutter 框架跨平台鸿蒙开发 —— Center 控件之完美居中之道
flutter·ui·华为·harmonyos·鸿蒙
小雨下雨的雨13 小时前
Flutter 框架跨平台鸿蒙开发 —— Icon 控件之图标交互美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨13 小时前
Flutter 框架跨平台鸿蒙开发 —— Placeholder 控件之布局雏形美学
flutter·ui·华为·harmonyos·鸿蒙系统
行者9614 小时前
OpenHarmony Flutter弹出菜单组件深度实践:从基础到高级的完整指南
flutter·harmonyos·鸿蒙
前端不太难14 小时前
Flutter / RN / iOS,在长期维护下的性能差异本质
flutter·ios