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: "你点击了三国演义!!!");
                        }
                    ),



                  ],
                ),
              ),


            ),
          ],
        ),


      ),
    );
  }

}
相关推荐
猫林老师2 小时前
Flutter for HarmonyOS开发指南(四):国际化与本地化深度实践
flutter·华为·harmonyos
猫林老师8 小时前
Flutter for HarmonyOS 开发指南(一):环境搭建与项目创建
flutter·华为·harmonyos
sunly_19 小时前
Flutter:视频预览功能
javascript·flutter·音视频
勤劳打代码1 天前
条分缕析 —— 通过 Demo 深入浅出 Provider 原理
flutter·面试·dart
2501_915918411 天前
Flutter 加固方案对比与实战,多工具组合的跨平台安全体系(Flutter App 加固/IPA 成品混淆/Ipa Guard CLI/自动化安全流程)
安全·flutter·ios·小程序·uni-app·自动化·iphone
Bryce李小白1 天前
Flutter中mixing的原理及应用场景
flutter
_大学牲1 天前
从 0 到上架:用 Flutter 一天做一款功德木鱼
前端·flutter·apple
嚴寒1 天前
2025最终!Mac配置Flutter全平台开发环境完整指南(亲测有效)
前端·flutter
Bryce李小白2 天前
Flutter版本管理工具FVM
flutter