news 2026/7/7 5:36:13

Flutter---GridView四大名著项目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter---GridView四大名著项目
效果图

原理

使用GridView.count实现

实现步骤

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

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

dependencies: fluttertoast: ^8.2.2 # 检查最新版本

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

import 'package:fluttertoast/fluttertoast.dart';

3.自定义控件

//自定义控件 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中使用自定义控件

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函数

性能优化

这个只能做短列表,因为每一个项都需要加入一个列表子项,有没有方法优化这个问题呢?

代码实例
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: "你点击了三国演义!!!"); } ), ], ), ), ), ], ), ), ); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 5:30:46

【从零构建分布式在线评测系统】二、Judge0服务器上的心跳程序

上一篇介绍了整体构架&#xff0c;这一篇介绍如何实现心跳程序。在ubuntu上使用.net程序有不少方法&#xff0c;我们采用使用标准框架的方式。一、工程配置1、类型&#xff1a;控制台应用——莫担心&#xff0c;它会得到一个dll&#xff0c;部署这个dll即可2、目标框架&#xf…

作者头像 李华
网站建设 2026/7/7 5:30:37

TCP/IP的参考模型:

CP的java实现&#xff1a; 客户端&#xff1a; 连接服务器Socket(serverIP, port); //port可以是约定&#xff0c; serverIP 用InetAddress.getByName("127.0.0.1"); 获得。发送消息. 用ossocket.getOutputStream();得到一个发送流对象。 然后再调用对象os的write(&…

作者头像 李华
网站建设 2026/7/7 5:28:59

基于大数据的农业环境管理平台的设计与实现毕业设计任务书

一、毕业设计题目 基于大数据的农业环境管理平台的设计与实现 二、研究背景与意义 现代农业发展逐步向数字化、智能化、精准化方向转型&#xff0c;农业环境是农作物生长、农业生产开展的核心基础&#xff0c;直接决定农作物产量、品质与农业生产效益。农业环境涵盖空气温湿度、…

作者头像 李华
网站建设 2026/7/7 5:28:25

GPU显存压力测试实战:用memtest_vulkan快速定位显卡稳定性问题

GPU显存压力测试实战&#xff1a;用memtest_vulkan快速定位显卡稳定性问题 【免费下载链接】memtest_vulkan Vulkan compute tool for testing video memory stability 项目地址: https://gitcode.com/gh_mirrors/me/memtest_vulkan 问题场景&#xff1a;当显卡开始"…

作者头像 李华
网站建设 2026/7/7 5:27:40

基于行车记录仪与YOLOv5的道路病害智能检测系统实践

&#x1f680; 30款热门AI模型一站整合&#xff0c;DeepSeek/GLM/Qwen 随心用&#xff0c;限时 5 折。 &#x1f449; 点击领海量免费额度 在道路养护和城市管理工作中&#xff0c;传统的人工巡检方式效率低下且成本高昂&#xff0c;而专业的道路检测车设备价格昂贵、部署复…

作者头像 李华