Flutter Widget 基础手把手教你创建自定义组件 📅 发布时间:2026/7/14 18:49:59 👁️ 浏览次数: 一、准备工作添加游戏逻辑文件在正式开始写 UI 之前我们需要先给项目添加一个游戏逻辑文件。这个文件负责处理猜词游戏的规则判断比如字母猜对了没有、位置对不对等与界面无关所以官方教程直接提供了现成的代码。操作步骤在项目的lib/目录下创建一个新文件game.dart。将官方提供的游戏逻辑代码复制进去可以从官方教程页面下载。在lib/main.dart文件顶部添加导入语句import package:flutter/material.dart; import game.dart; // 新增这一行这个文件里定义了一些关键概念其中最重要的是HitType枚举它表示猜测结果的类型HitType.hit字母和位置都猜对了绿色HitType.partial字母对了但位置不对黄色HitType.miss字母完全猜错了灰色HitType.none还没有猜测白色如果你玩过 Wordle对这几种状态一定不陌生。二、什么是 StatelessWidget在 Flutter 中Widget 分为两大类StatelessWidget无状态组件一旦创建内容就固定不变。适合展示静态内容。StatefulWidget有状态组件可以根据用户操作或数据变化来更新界面。后续教程会详细讲解。今天我们要创建的Tile组件就是一个 StatelessWidget。为什么因为每个方块的内容显示什么字母、什么颜色在创建时就已经确定了不需要在运行过程中自己改变。你可以把 StatelessWidget 想象成一张打印好的卡片——上面的内容在打印时就定了不会再变。三、创建你的第一个自定义 Widget3.1 定义 Tile 类在main.dart文件中MainApp类的下方添加以下代码class Tile extends StatelessWidget { const Tile(this.letter, this.hitType, {super.key}); final String letter; final HitType hitType; override Widget build(BuildContext context) { return Container(); } }别急我们一行一行来拆解。3.2 理解构造函数const Tile(this.letter, this.hitType, {super.key});这是 Tile 的构造函数。构造函数的作用是当你要创建一个 Tile 时告诉它需要哪些信息。this.letter这个方块要显示的字母比如 “A”、“B”。this.hitType猜测结果的类型决定方块的颜色。{super.key}Flutter 内部用来追踪组件的标识符照写就行不用深究。打个比方构造函数就像点菜单上的选项。你告诉服务员Flutter“我要一个显示字母 A 的绿色方块”服务员就按你的要求端上来。这就是让 Widget 可复用的关键。同一个 Tile 类传入不同的参数就能显示不同的字母和颜色。3.3 理解 build 方法override Widget build(BuildContext context) { return Container(); }每个 Widget 都必须有一个build方法。它的职责很简单告诉 Flutter 这个组件长什么样。它必须返回另一个 Widget。现在返回的是一个空的Container()所以屏幕上什么都看不到。接下来我们会一步步给它化妆。四、使用你的自定义 Widget在看到效果之前我们先把 Tile 放到界面上。修改MainApp的build方法class MainApp extends StatelessWidget { const MainApp({super.key}); override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: Tile(A, HitType.hit), // 使用自定义的 Tile 组件 ), ), ); } }这里我们创建了一个 Tile传入字母A和猜测类型HitType.hit猜对了。此时运行应用屏幕还是空白的因为 Tile 的 build 方法还只返回一个空容器。五、认识 Container 组件Container是 Flutter 中最常用的组件之一。你可以把它理解为一个万能盒子可以设置大小、颜色、边框、内边距等各种样式。5.1 设置大小先给方块一个固定的宽高override Widget build(BuildContext context) { return Container( width: 60, height: 60, ); }这样就创建了一个 60×60 像素的方块。虽然现在还是看不见因为没有颜色但它在布局中已经占了位置。5.2 添加边框BoxDecoration接下来用BoxDecoration给方块加上边框override Widget build(BuildContext context) { return Container( width: 60, height: 60, decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), ), ); }BoxDecoration是 Container 的化妆师它可以给容器添加边框、背景色、圆角、阴影等装饰效果。这里我们用Border.all()给四个边都加上了浅灰色的边框。热重载一下按r你应该能看到屏幕中央出现了一个带边框的小方块。5.3 根据猜测结果变换颜色这是最有趣的部分。我们需要根据hitType的值来决定方块的背景颜色。Dart 语言提供了一种叫做switch 表达式的语法非常适合这种根据不同条件返回不同值的场景decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), color: switch (hitType) { HitType.hit Colors.green, // 猜对了 → 绿色 HitType.partial Colors.yellow, // 位置不对 → 黄色 HitType.miss Colors.grey, // 猜错了 → 灰色 _ Colors.white, // 默认 → 白色 }, ),这段代码的逻辑很直观如果猜对了就显示绿色位置不对就显示黄色猜错了就显示灰色其他情况显示白色。六、添加文字内容最后一步在方块中间显示字母。这里用到两个我们已经认识的 WidgetCenter居中和Text文字。override Widget build(BuildContext context) { return Container( width: 60, height: 60, decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), color: switch (hitType) { HitType.hit Colors.green, HitType.partial Colors.yellow, HitType.miss Colors.grey, _ Colors.white, }, ), child: Center( child: Text( letter.toUpperCase(), style: Theme.of(context).textTheme.titleLarge, ), ), ); }几个要点child属性大多数 Flutter Widget 都有child放一个子组件或children放多个子组件属性。这是 Widget 嵌套的核心机制。letter.toUpperCase()把字母转成大写显示。Theme.of(context).textTheme.titleLarge使用应用主题中预定义的大号标题字体样式省去手动设置字号和字重。热重载后你应该能看到一个绿色的方块中间显示着大写的字母 “A”。6.1 试着切换颜色你可以通过修改传入 Tile 的参数来观察不同颜色的效果// 绿色猜对了 child: Tile(A, HitType.hit) // 黄色字母对了位置不对 child: Tile(A, HitType.partial) // 灰色完全猜错了 child: Tile(A, HitType.miss)每次修改后按r热重载颜色会立刻切换非常直观。七、完整的 Widget 树让我们回顾一下现在的 Widget 树结构MainApp └── MaterialApp └── Scaffold └── Center └── Tile (我们的自定义组件) └── Container (60x60, 带边框和背景色) └── Center └── Text (A)你会发现创建自定义 Widget 的本质就是把多个现有的 Widget 组合在一起打包成一个新组件。这就像用乐高积木搭建基础积木Container、Center、Text是 Flutter 提供的你通过组合它们来创造属于自己的零件Tile然后再用这些零件组装出更复杂的界面。八、本节知识点小结StatelessWidget无状态组件适合展示固定内容。通过继承 StatelessWidget 类并实现 build 方法来创建自定义组件。构造函数传参通过构造函数接收外部数据如字母和颜色类型是让 Widget 可复用的核心方式。同一个 Widget 类传入不同参数就能呈现不同的效果。Container 和 BoxDecorationContainer 是万能盒子用来设置大小、内边距等。BoxDecoration 是它的化妆师负责添加边框、背景色、阴影等视觉装饰。child 和 childrenFlutter 中组件的嵌套通过 child单个子组件或 children多个子组件属性实现这是构建 Widget 树的基本方式。九、下一步学习现在你已经学会了创建自定义 Widget下一课将进入布局Layout章节学习如何用Column、Row等布局组件把多个 Tile 排列成游戏需要的网格。猜词游戏的界面正在一步步成型我们下篇文章见参考资料Flutter 官方教程 - Widget Fundamentals
音乐解密工具:数字音乐资产的自主掌控之道 音乐解密工具:数字音乐资产的自主掌控之道 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目地址: https://gitcode.… 2026/5/17 11:02:18
资源获取效率工具:重构科研数据访问模式的开源解决方案 资源获取效率工具:重构科研数据访问模式的开源解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改(改自6.1.4版本) ,自用,去推广&… 2026/5/17 11:02:18
计算机毕业设计之springboot餐厅店内点餐系统 随着社会的发展,系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息,但各种信息鱼龙混杂,信息真假难以辨别。为了方便用户更好的获得餐厅店内点餐信息,因此,设计一种安全高效的餐厅店内点餐系统极为重要。 … 2026/5/17 11:02:17
凝思操作系统网络配置进阶:静态IP、虚拟IP与多网卡绑定实战 1. 静态IP配置实战:单网卡多地址方案在企业服务器部署中,经常需要为单块物理网卡配置多个IP地址。这种方案通常用于实现网络隔离或服务分离,比如在同一台服务器上同时运行测试环境和生产环境服务。配置文件实操:打开/etc/network/… 2026/7/14 18:49:09
Dump文件实战解析:从内存转储到故障定位 1. 什么是Dump文件?当你的程序突然崩溃时,系统会自动生成一个特殊的文件,这就是我们常说的Dump文件。它就像是程序在崩溃瞬间拍下的一张"快照",完整记录了当时内存中的所有数据、线程状态和调用堆栈等信息。想象一下&am… 2026/7/14 18:49:09
STM32与ISOM8710数字隔离器的高压安全设计实践 1. 高压安全隔离的必要性与技术选型在工业自动化、电力电子和医疗设备领域,高压与低压电路之间的安全隔离是系统设计的核心需求。当STM32微控制器需要监测或控制380V交流电机、光伏逆变器或医疗设备时,如果没有可靠的隔离措施,高压侧的浪涌、… 2026/7/14 18:49:09
无限创意画布AI工具怎么选?五大热门工具实力排行与场景推荐 同一个素材,30个平台要出30套不同尺寸。投放团队砍掉一半时间在做重复排版,而不是优化内容。无限创意画布AI工具怎么选? 核心不是比谁功能多,而是看它能不能把你最耗时的那一步砍掉。投包、即梦、JokerAIx、Canva、Lovart五个工具,分别适合完全不同的工作流。选错大… 2026/7/14 18:47:09
Qt学习(开发环境Visual Studio)6.串口助手 本文将使用Qt来做一个串口助手,并实现通信。 首先了解一下串口助手,简单来说,串口助手就是电脑和设备之间的翻译官兼搬运工。 它的工作原理可以浓缩为三步: 物理连接靠“伪装”:现在电脑没有老式串口,全… 2026/7/14 18:45:08
从核心点到噪声点:DBSCAN密度聚类算法实战解析 1. 初识DBSCAN:当数据像星空一样分布第一次接触DBSCAN时,我被它的思维方式惊艳到了——它不像K-Means那样要求数据必须乖乖围成球形,而是像观察星空一样,寻找那些星星密集的星座区域。想象你站在郊外仰望夜空,有些区域… 2026/7/14 18:43:08
XUnity.AutoTranslator 游戏实时翻译插件:从原理到实战的完整指南 1. 项目概述:当游戏语言成为一堵墙作为一名玩了十几年日系、欧美独立游戏的“老油条”,我太懂那种面对一款心仪已久、画风玩法都戳中G点的游戏,却因为语言不通而望而却步的痛了。尤其是那些基于Unity引擎开发的、体量不大但内容精良的作品&am… 2026/7/14 0:05:14
2026普通文员学数据分析的价值 一、2026年普通文员学习数据分析的必要性随着数字化转型加速,数据分析技能正逐渐成为职场基础能力。普通文员学习数据分析可以提升工作效率、增强竞争力,并为职业转型提供更多可能性。二、数据分析对文员的价值自动化办公:通过数据分析工具&a… 2026/7/14 0:05:14
2026从计划员到主管,生产管理者学数据分析有用吗? 一、生产管理领域的职业发展路径 从计划员到主管的角色转变,是生产管理者职业发展的典型路径。计划员主要负责生产排程、库存管理和资源协调等基础工作,而主管则需要承担团队管理、决策支持和效率优化等更高级别的职责。这种转变不仅仅是职位的提升&… 2026/7/14 0:05:14
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/13 8:31:55
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/14 18:25:04
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/14 5:09:41