【GLM-5 陪练式创意 UI 实战】第一篇:创意魔法盒 ------ 用 AI 生成 "开心" 主题 Flutter UI,搞定深浅色与响应式
目录
[【GLM-5 陪练式创意 UI 实战】第一篇:创意魔法盒 ------ 用 AI 生成 "开心" 主题 Flutter UI,搞定深浅色与响应式](#【GLM-5 陪练式创意 UI 实战】第一篇:创意魔法盒 —— 用 AI 生成 “开心” 主题 Flutter UI,搞定深浅色与响应式)
[引 言](#引 言)
[1 测试背景与准备](#1 测试背景与准备)
[2 核心提示词设计](#2 核心提示词设计)
[3 情绪驱动的设计拆解(GLM-5 输出解析)](#3 情绪驱动的设计拆解(GLM-5 输出解析))
[3.1 配色方案:暖色调传递快乐感](#3.1 配色方案:暖色调传递快乐感)
[3.2 动画效果:让 UI "活" 起来](#3.2 动画效果:让 UI “活” 起来)
[4 核心代码实现与解析](#4 核心代码实现与解析)
[4.1 主题配置:深浅色模式一键切换](#4.1 主题配置:深浅色模式一键切换)
[4.2 动画管理:双控制器实现多效果联动](#4.2 动画管理:双控制器实现多效果联动)
[4.3 响应式布局:适配手机 / 桌面双端](#4.3 响应式布局:适配手机 / 桌面双端)
[4.4 核心 UI 组件:情绪与功能的融合](#4.4 核心 UI 组件:情绪与功能的融合)
[5 本地效果验证:从项目创建到运行调试](#5 本地效果验证:从项目创建到运行调试)
[5.1 项目初始化](#5.1 项目初始化)
[5.2 进入项目目录](#5.2 进入项目目录)
[5.3 替换核心代码](#5.3 替换核心代码)
[5.4 启动 Web 服务](#5.4 启动 Web 服务)
[6 实践感悟](#6 实践感悟)
✨ 主题 3:创意魔法盒 ------ 情绪驱动的动态 UI 生成器
活动仓库链接:https://atomgit.com/GitCode/0daymodel
引 言
完成【主题 1:初体验拾光 ------AI 陪练式前端新手入门】系列后,我将目光投向了主题 3:创意魔法盒 ------ 情绪驱动的动态 UI 生成器。这一主题的核心魅力在于 "让 UI 随情绪流动",而 Flutter 的跨平台特性、原生级动画支持,恰好能完美承载 "情绪驱动" 的动态设计需求。
本次我将以 "开心、明亮、活泼" 为核心情绪,借助 GLM-5 的陪练能力,从 0 到 1 生成可直接运行的 Flutter UI 组件,并学习深浅色模式切换 与移动端响应式适配两大核心需求,开启情绪 UI 的实战之旅。
1 测试背景与准备
1. 主题 3 核心任务
根据征文要求,情绪 UI 设计师需完成三步核心任务:
- 按 "开心" 情绪生成配色、动画与可运行的 Flutter 代码;
- 迭代生成 "科技感" 风格代码并说明差异;
- 整合 Demo 并部署到 AtomGit。
本篇聚焦第一步:实现 "开心" 主题的基础 UI。
2. GLM-5 参数优化
为避免代码截断,结合之前的测试经验,我对 GLM-5 做了针对性参数调整(截图如下):
Max Tokens:从 4096 提升至 8192,释放足够的代码输出空间;Temperature:降至 0.2,保证输出代码的稳定性与聚焦性;- 其他参数保持默认,确保 AI 输出贴合需求、无冗余内容。

2 核心提示词设计
结合主题 3 要求与 Flutter 技术栈,我设计了相关的提示词,锁定 "情绪 UI 设计师" 角色,明确输出边界,避免 AI 发散:
你现在是一个"情绪UI设计师",我会用文字描述我的情绪和需求,请你严格按照以下步骤执行,并且全程使用Flutter(Dart语言)实现:
1. 我当前的情绪是:我现在很开心,想要一个明亮、活泼的个人主页。
- 生成对应的UI配色方案(明确色值)、动画效果和可直接运行的Flutter组件代码。
- 代码必须支持深色/浅色模式切换,并且响应式适配移动端。
2. 当我后续说"现在我想换成科技感的风格"时,你需要迭代生成新的Flutter代码,并详细说明与上一版的差异。
3. 最后,生成一个完整的"情绪网页"Demo(Flutter Web),并提供部署到AtomGit的详细步骤说明。
现在,请先执行第一步:生成"开心/明亮/活泼"主题的个人主页。如果内容超过单次输出限制,请在末尾标注"[未完待续]",我会继续请求生成剩余部分。
提示词设计逻辑:
-
明确角色与技术栈:锁定 "情绪 UI 设计师",强制使用 Flutter;
-
拆解任务步骤:先完成第一步,避免一次性需求过多导致截断;
-
防截断约定:标注 "[未完待续]",为长内容输出兜底。

3 情绪驱动的设计拆解(GLM-5 输出解析)
基于 "开心、明亮、活泼" 的情绪,GLM-5 为我量身打造了一套贴合情绪的设计方案,完美实现了 "情绪→设计" 的转化。
用户希望我扮演"情绪UI设计师",并使用Flutter(Dart)实现特定的UI设计。
**当前任务:**
执行第一步:生成"开心/明亮/活泼"主题的个人主页。
**需求:**
1. **情绪:** 开心、明亮、活泼。
2. **输出:**
* UI配色方案(明确色值)。
* 动画效果。
* 可直接运行的Flutter组件代码。
* 支持深色/浅色模式切换。
* 响应式适配移动端。
3. **限制:** 如果输出太长,标注"[未完待续]"。
**第一步分析与设计:**
* **主题(开心/明亮/活泼):**
* *颜色:* 高饱和度,暖色调。黄色、橙色、粉色、青色。
* *浅色模式:* 白色背景,明亮的强调色。
* *深色模式:* 深灰/黑色背景,霓虹/柔和的强调色以保持"活泼"感而不刺眼。
* *排版:* 圆角,俏皮的字体(Flutter中通常使用标准字体,但样式很重要)。
* **配色方案(色值):**
* 主色:阳光黄 (#FFD740) 或 活力橙 (#FF7043)。让我们选用一种混合了珊瑚粉 (#FF8A65) 的明亮黄色 (#FFD54F)。
* 辅色:青色 (#4DD0E1) 或 石灰绿 (#AED581)。
* 背景(浅色):#FAFAFA(纯白太平淡)。
* 背景(深色):#121212 或 #1E1E1E。
* 文本(浅色):深灰 #37474F。
* 文本(深色):白色 #FFFFFF。
* **动画效果:**
* "活泼"意味着运动。
* Hero头像的浮动动画。
* 卡片的交错淡入。
* 按钮的弹跳效果。
* **Flutter实现细节:**
* `MaterialApp` 配置 `theme` 和 `darkTheme`。
* `ThemeData` 定义。
* `AnimatedBuilder` 或 `AnimationController` 用于浮动效果。
* `LayoutBuilder` 或 `MediaQuery` 用于响应式布局。
* `Switch` 或 `IconButton` 用于主题切换。
**起草代码结构:**
1. `main.dart`:入口点。
2. `MyApp`:主题配置。
3. `HomePage`:主屏幕。
* `AppBar`:标题 + 主题切换。
* `Body`:`SingleChildScrollView` 或 `ListView`。
* `Header`:头像 + 名字 + 简介。
* `Stats`:关注者/帖子行。
* `Content`:卡片网格或列表。
**完善"活泼"方面:**
* 使用 `Container` 装饰圆角和渐变。
* 使用 `StaggeredGrid` 或简单的 `Wrap` 来营造活泼的布局感。
**分步执行计划:**
1. **定义配色方案:** 列出十六进制代码。
2. **描述动画:** 解释逻辑(例如,使用 `Sin` 实现浮动)。
3. **编写代码:**
* 导入。
* 主函数。
* 主题数据(浅色/深色)。
* 主页Widget。
* 头部Widget(动画)。
* 卡片Widget。
* 响应式逻辑(检查宽度)。
**起草过程中的自我修正/完善:**
* *限制检查:* 用户要求"可直接运行"。我需要确保代码是独立的(如果可能的话,不依赖外部包,或者使用标准包如 `provider` 进行状态管理,但为了简单和单文件,`setState` 更好)。
* *深色模式:* 需要一个变量来跟踪主题状态。
* *响应式:* 使用 `MediaQuery.of(context).size.width`。
**起草内容:**
* *标题:* "快乐空间"。
* *简介:* "分享快乐与创意。"
* *卡片:* "我的爱好"、"旅行日记"、"美食地图"。
**让我们编写实际的Flutter代码逻辑(心理草稿):**
```dart
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late AnimationController _floatController;
// ... 初始化动画 ...
// ... 构建方法 ...
}
```
**配色方案定义:**
* 浅色主色:`Color(0xFFFFD54F)` (黄色)
* 浅色辅色:`Color(0xFFFF7043)` (橙色)
* 深色主色:`Color(0xFF4DD0E1)` (青色 - 在深色模式下看起来很酷)
* 深色辅色:`Color(0xFFAB47BC)` (紫色)
**响应式布局:**
* 如果宽度 < 600:列表视图(移动端)。
* 如果宽度 >= 600:网格视图(平板/桌面)。
**输出结构:**
1. 设计理念(颜色与动画)。
2. Flutter代码块。
3. 结束语。
让我们生成回复收到!作为你的"情绪UI设计师",我非常乐意为你将这份"开心、明亮、活泼"的情绪转化为具体的Flutter代码。
以下是第一步的详细设计与实现:
### 1. 设计理念与方案
**情绪关键词:** 开心、明亮、活泼、阳光。
**UI 配色方案:**
为了传达"开心"的情绪,我们选用高饱和度、暖色调为主,搭配清新的冷色调作为点缀,营造阳光明媚的感觉。
* **浅色模式:**
* 主背景: `#FFF9F3` (极淡的暖白,像阳光晒过的纸张)
* 主色调: `#FFD740` (向日葵黄,代表活力与快乐)
* 次色调: `#FF7043` (珊瑚橙,温暖且富有亲和力)
* 强调色: `#26A69A` (青绿色,用于按钮或链接,平衡暖色)
* 文字色: `#37474F` (深蓝灰,比纯黑更柔和)
* **深色模式:**
* 主背景: `#121212` (标准Material深色背景)
* 表面色: `#1E1E1E` (卡片背景)
* 主色调: `#FFE57F` (亮黄色,在深色背景下更发光)
* 次色调: `#FF8A65` (深色模式下的橙色)
* 文字色: `#EEEEEE` (柔白)
**动画效果:**
1. **弹性呼吸动画:** 头像和主要卡片具有轻微的缩放呼吸效果,模拟心跳或呼吸的节奏,赋予界面生命力。
2. **交错入场:** 页面元素依次滑入,配合弹性曲线,像蹦跳着出场一样。
3. **交互反馈:** 按钮点击时有明显的缩放与发光效果。
---
### 2. Flutter 组件代码实现
这是一个完整的 `main.dart` 文件,支持深色/浅色切换,并适配移动端。
```dart
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Happy Mood UI',
debugShowCheckedModeBanner: false,
theme: _buildLightTheme(),
darkTheme: _buildDarkTheme(),
themeMode: ThemeMode.system, // 跟随系统
home: const HappyHomePage(),
);
}
// 构建明亮主题
ThemeData _buildLightTheme() {
final base = ThemeData.light(useMaterial3: true);
return base.copyWith(
scaffoldBackgroundColor: const Color(0xFFFFF9F3),
colorScheme: base.colorScheme.copyWith(
primary: const Color(0xFFFFD740),
secondary: const Color(0xFFFF7043),
tertiary: const Color(0xFF26A69A),
surface: const Color(0xFFFFFFFF),
onSurface: const Color(0xFF37474F),
),
cardTheme: CardTheme(
color: Colors.white,
elevation: 4,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
textTheme: base.textTheme.apply(
bodyColor: const Color(0xFF37474F),
displayColor: const Color(0xFF37474F),
),
);
}
// 构建深色主题
ThemeData _buildDarkTheme() {
final base = ThemeData.dark(useMaterial3: true);
return base.copyWith(
scaffoldBackgroundColor: const Color(0xFF121212),
colorScheme: base.colorScheme.copyWith(
primary: const Color(0xFFFFE57F),
secondary: const Color(0xFFFF8A65),
tertiary: const Color(0xFF80CBC4),
surface: const Color(0xFF1E1E1E),
onSurface: const Color(0xFFEEEEEE),
),
cardTheme: CardTheme(
color: const Color(0xFF1E1E1E),
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
);
}
}
class HappyHomePage extends StatefulWidget {
const HappyHomePage({super.key});
@override
State<HappyHomePage> createState() => _HappyHomePageState();
}
class _HappyHomePageState extends State<HappyHomePage>
with TickerProviderStateMixin {
late AnimationController _breathController;
late AnimationController _entryController;
// 模拟主题切换状态(用于演示,实际由系统控制)
var _isDarkMode = false;
@override
void initState() {
super.initState();
// 1. 呼吸动画:无限循环,像心跳一样
_breathController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1500),
)..repeat(reverse: true);
// 2. 入场动画:一次性
_entryController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1200),
)..forward();
}
@override
void dispose() {
_breathController.dispose();
_entryController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorScheme = theme.colorScheme;
final size = MediaQuery.of(context).size;
final isMobile = size.width < 600;
return Scaffold(
body: SafeArea(
child: AnimatedBuilder(
animation: _entryController,
builder: (context, child) {
return Stack(
children: [
// 背景装饰圆形
Positioned(
top: -50,
right: -50,
child: AnimatedBuilder(
animation: _breathController,
builder: (context, _) {
final scale = 1.0 + _breathController.value * 0.1;
return Transform.scale(
scale: scale,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: colorScheme.primary.withOpacity(0.2),
shape: BoxShape.circle,
),
),
);
},
),
),
// 主要内容
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 顶部栏:切换主题
_buildTopBar(colorScheme),
// 滑动入场效果
SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0.5),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _entryController,
curve: Curves.elasticOut, // 弹性曲线
)),
child: FadeTransition(
opacity: _entryController,
child: _buildContent(context, isMobile, colorScheme),
),
),
],
),
),
],
);
},
),
),
);
}
// 顶部栏
Widget _buildTopBar(ColorScheme colorScheme) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"My Mood Space",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
IconButton(
icon: Icon(
_isDarkMode ? Icons.light_mode : Icons.dark_mode,
color: colorScheme.secondary,
),
onPressed: () {
setState(() {
_isDarkMode = !_isDarkMode;
});
// 实际应用中这里会调用更高层级的状态管理
// 演示目的:仅切换本地变量,实际主题由MaterialApp控制
},
),
],
);
}
// 核心内容布局
Widget _buildContent(BuildContext context, bool isMobile, ColorScheme colorScheme) {
return Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
_buildHeader(colorScheme),
const SizedBox(height: 30),
_buildStatCards(colorScheme),
const SizedBox(height: 30),
Text(
"今日心情记录",
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
const SizedBox(height: 15),
_buildMoodGrid(isMobile, colorScheme),
],
),
),
);
}
// 头像与简介
Widget _buildHeader(ColorScheme colorScheme) {
return Row(
children: [
// 头像呼吸动画
AnimatedBuilder(
animation: _breathController,
builder: (context, child) {
final value = math.sin(_breathController.value * math.pi);
return Transform.scale(
scale: 1.0 + (value * 0.05),
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: colorScheme.primary, width: 3),
),
child: const CircleAvatar(
radius: 40,
backgroundImage: NetworkImage('https://picsum.photos/200'), // 随机头像
backgroundColor: Colors.transparent,
),
),
);
},
),
const SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"你好,开心鬼!",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w800,
color: colorScheme.onSurface,
),
),
const SizedBox(height: 5),
Text(
"今天也是元气满满的一天 ✨",
style: TextStyle(
fontSize: 16,
color: colorScheme.onSurface.withOpacity(0.7),
),
),
],
),
),
],
);
}
// 统计卡片
Widget _buildStatCards(ColorScheme colorScheme) {
return Row(
children: [
_buildSingleStat("128", "快乐时刻", colorScheme.primary),
const SizedBox(width: 15),
_buildSingleStat("56", "分享瞬间", colorScheme.secondary),
const SizedBox(width: 15),
_buildSingleStat("99%", "心情指数", colorScheme.tertiary),
],
);
}
Widget _buildSingleStat(String num, String label, Color color) {
return Expanded(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 15),
decoration: BoxDecoration(
color: color.withOpacity(0.15),
borderRadius: BorderRadius.circular(15),
),
child: Column(
children: [
Text(num, style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: color)),
Text(label, style: TextStyle(fontSize: 12, color: color.withOpacity(0.8))),
],
),
),
);
}
// 心情网格
Widget _buildMoodGrid(bool isMobile, ColorScheme colorScheme) {
final items = [
_MoodItem("🌞", "阳光早晨", "开启美好一天"),
_MoodItem("🍦", "甜蜜下午茶", "草莓冰淇淋"),
_MoodItem("🎨", "创意涂鸦", "画出彩虹"),
_MoodItem("🎵", "快乐旋律", "哼着小曲"),
];
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isMobile ? 2 : 4,
crossAxisSpacing: 15,
mainAxisSpacing: 15,
childAspectRatio: 1.2,
),
itemCount: items.length,
itemBuilder: (context, index) {
// 交错动画延迟
return AnimatedBuilder(
animation: _entryController,
builder: (context, child) {
final delay = index * 0.1;
final animVal = Curves.easeOut.transform(
math.max(0.0, _entryController.value - delay) / (1.0 - delay),
);
return Transform.scale(
scale: animVal,
child: Opacity(
opacity: animVal,
child: _buildMoodCard(items[index], colorScheme),
),
);
},
);
},
);
}
Widget _buildMoodCard(_MoodItem item, ColorScheme colorScheme) {
return Card(
child: InkWell(
onTap: () {}, // 点击交互
borderRadius: BorderRadius.circular(20),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(item.emoji, style: const TextStyle(fontSize: 28)),
const SizedBox(height: 8),
Text(
item.title,
style: TextStyle(
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
Text(
item.desc,
style: TextStyle(
fontSize: 12,
color: colorScheme.onSurface.withOpacity(0.6),
),
),
],
),
),
),
);
}
}
class _MoodItem {
final String emoji;
final String title;
final String desc;
_MoodItem(this.emoji, this.title, this.desc);
}
```
### 3. 代码说明
1. **响应式适配**:通过 `MediaQuery.of(context).size.width` 判断屏幕宽度,动态调整网格列数(`crossAxisCount`),在手机上显示2列,宽屏显示4列。
2. **主题切换**:定义了 `_buildLightTheme` 和 `_buildDarkTheme`。代码中包含了一个切换按钮(演示用),实际运行时会自动跟随系统设置。
3. **动画细节**:
* 使用 `Curves.elasticOut` 实现"活泼"的弹性入场效果。
* 背景的圆形装饰和头像使用了 `AnimatedBuilder` 配合 `sin` 函数实现无限循环的呼吸效果,让界面感觉是"活"的。
第一步已完成。请确认这个"开心/明亮/活泼"的风格是否符合你的预期。如果满意,请发出下一步指令:"现在我想换成科技感的风格"。
3.1 配色方案:暖色调传递快乐感
配色是情绪表达的核心,GLM-5 选用高饱和度暖色调,搭配柔和辅助色,既贴合 "开心" 情绪,又保证了视觉舒适度。
| 模式 | 主背景 | 主色调 | 次色调 | 强调色 | 文字色 |
|---|---|---|---|---|---|
| 浅色模式 | #FFF9F3(暖白) | #FFD740(向日葵黄) | #FF7043(珊瑚橙) | #26A69A(青绿色) | #37474F(深蓝灰) |
| 深色模式 | #121212(深黑) | #FFE57F(亮黄) | #FF8A65(浅橙) | #80CBC4(浅青绿) | #EEEEEE(柔白) |
设计巧思:浅色模式用暖白打底,黄色 / 橙色凸显活力;深色模式保留明亮主色,在深色背景下形成 "霓虹感",既延续活泼情绪,又符合夜间视觉习惯。
3.2 动画效果:让 UI "活" 起来
为强化 "活泼" 感,GLM-5 设计了三套核心动画,精准匹配 "开心" 的灵动氛围:
- 呼吸动画:头像与背景圆形装饰的无限循环缩放,模拟心跳节奏,赋予界面生命力;
- 弹性入场动画 :页面核心元素通过
Curves.elasticOut曲线滑入,像 "蹦跳着出场"; - 交错入场动画:心情卡片按索引延迟显示,营造层次感与节奏感。
4 核心代码实现与解析
GLM-5 生成的main.dart是完整的可运行代码,核心分为主题配置 、动画管理 、响应式布局 、核心 UI 组件四大模块,以下是关键部分的解析与优化说明。
4.1 主题配置:深浅色模式一键切换
通过_buildLightTheme和_buildDarkTheme封装ThemeData,结合MaterialApp的theme/darkTheme参数,实现系统主题跟随,同时预留手动切换入口。
// 明亮主题构建
ThemeData _buildLightTheme() {
final base = ThemeData.light(useMaterial3: true);
return base.copyWith(
scaffoldBackgroundColor: const Color(0xFFFFF9F3),
colorScheme: base.colorScheme.copyWith(
primary: const Color(0xFFFFD740),
secondary: const Color(0xFFFF7043),
tertiary: const Color(0xFF26A69A),
),
cardTheme: CardTheme(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), // 圆角强化活泼感
),
);
}
// 深色主题构建(核心差异:调整主色亮度与背景色)
ThemeData _buildDarkTheme() {
final base = ThemeData.dark(useMaterial3: true);
return base.copyWith(
scaffoldBackgroundColor: const Color(0xFF121212),
colorScheme: base.colorScheme.copyWith(
primary: const Color(0xFFFFE57F), // 提亮黄色,适配深色背景
secondary: const Color(0xFFFF8A65),
),
);
}
4.2 动画管理:双控制器实现多效果联动
借助TickerProviderStateMixin,创建两个动画控制器,分别管理呼吸动画 (无限循环)和入场动画(一次性执行)。
late AnimationController _breathController; // 呼吸动画控制器
late AnimationController _entryController; // 入场动画控制器
@override
void initState() {
super.initState();
// 呼吸动画:1500ms循环,反向重复
_breathController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1500),
)..repeat(reverse: true);
// 入场动画:1200ms执行一次
_entryController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1200),
)..forward();
}
4.3 响应式布局:适配手机 / 桌面双端
通过MediaQuery获取屏幕宽度,动态调整网格列数,实现 "移动端 2 列、桌面端 4 列" 的自适应布局。
final size = MediaQuery.of(context).size;
final isMobile = size.width < 600;
// 网格布局配置
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isMobile ? 2 : 4, // 动态列数
crossAxisSpacing: 15,
mainAxisSpacing: 15,
childAspectRatio: 1.2,
),
4.4 核心 UI 组件:情绪与功能的融合
- 头部区域:带呼吸动画的头像 + 活力文案,直接传递 "开心" 情绪;
- 统计卡片:用淡色渐变 + 圆角设计,强化活泼感,展示情绪相关数据;
- 心情卡片:交错入场的卡片网格,搭配 emoji 图标,直观呈现情绪记录。
5 本地效果验证:从项目创建到运行调试
5.1 项目初始化
在终端执行以下命令,创建一个全新的 Flutter 项目:
flutter create happy_mood_ui
执行后,终端会输出项目创建进度,并提示:
- 项目代码位于
happy_mood_ui/lib/main.dart; - 若出现 Java 与 Gradle 版本兼容提示,可按指引配置 JDK 路径或更新 Gradle 版本(本次测试优先聚焦 Web 端,可暂时忽略 Android 相关兼容提示)。
5.2 进入项目目录
执行命令进入项目根目录:
cd happy_mood_ui
5.3 替换核心代码
将 GLM-5 生成的完整代码复制到 Flutter 项目的 lib/main.dart,覆盖原有内容,确保代码可直接运行。
5.4 启动 Web 服务
在终端执行以下命令,启动 Chrome 浏览器预览:
flutter run -d chrome
本地运行效果如下(截图如下):


效果验证要点:
- 响应式适配:缩小浏览器窗口至手机尺寸,卡片自动从 4 列切换为 2 列,布局无错乱;
- 动画效果:头像呼吸动画流畅,页面入场有弹性,卡片交错显示有层次感;
- 主题切换:点击顶部明暗模式按钮,配色随模式同步切换,视觉效果统一。
6 实践感悟
- AI 的效率优势:传统开发中,从 "情绪分析→设计→代码实现" 需数小时,而 GLM-5 在优化参数后,10 分钟内就输出了完整的可运行代码,大幅降低了情绪 UI 的开发门槛;
- 参数调整的关键 :初始测试中代码截断,提升
Max Tokens+ 降低Temperature后,AI 能完整输出包含动画、响应式的复杂代码,证明参数适配是 AI 辅助开发的核心前提; - 情绪与技术的融合:GLM-5 能精准捕捉 "开心" 情绪的视觉特征,将暖色调、弹性动画与 Flutter 技术结合,真正实现了 "情绪驱动 UI" 的设计理念。
参与链接:
GLM-5 在线体验:https://ai.atomgit.com/zai-org/GLM-5/model-inference