欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
FlutterUnit 原始仓库:
https://gitcode.com/qq_30447263/FlutterUnit
仓库版本

实际示例还原效果
原仓库效果:

还原大致效果:



1. 项目介绍
FlutterUnit 是一个功能强大的 Flutter 组件百科全书应用,旨在帮助开发者快速了解和学习 Flutter 中的各种组件。本项目参考了 FlutterUnit 开源项目的设计理念,实现了一个适配鸿蒙平台的组件展示和演示平台。
1.1 项目目标
- 还原 FlutterUnit 应用的核心 UI 效果和功能
- 确保应用在鸿蒙平台上的正常运行
- 展示 Flutter 组件的使用方法和效果
- 提供一个直观的组件展示平台,帮助开发者快速了解 Flutter 组件
1.2 技术栈
- 框架:Flutter 3.35.7
- 语言:Dart
- UI 组件:Material 3
- 状态管理:setState
- 导航:Navigator
1.3 开源仓库地址
- FlutterUnit 原始仓库 :https://gitcode.com/qq_30447263/FlutterUnit
- 本项目仓库 :项目地址
2. 核心功能设计
2.1 功能模块
FlutterUnit 组件百科适配项目包含以下核心功能模块:
| 模块名称 | 功能描述 | 实现方式 |
|---|---|---|
| 启动页面 | 展示应用标志和品牌信息 | 自定义布局和绘制 |
| 组件列表页面 | 展示 Flutter 组件卡片 | GridView 布局 |
| 标签栏 | 分类展示不同类型的组件 | 横向滚动的标签栏 |
| 底部导航 | 切换不同功能页面 | BottomNavigationBar |
2.2 页面结构
应用采用底部导航栏的结构,包含三个主要页面:
- 启动页面:展示应用标志和品牌信息
- 组件列表页面:展示各种 Flutter 组件的卡片
- 收藏页面:展示用户收藏的组件(暂时使用组件列表页面)
3. 技术架构
3.1 项目结构
lib/
├── main.dart # 应用入口
└── components/ # 组件目录
├── splash/ # 启动页面组件
├── component_list/ # 组件列表页面组件
└── navigation/ # 导航组件
3.2 组件结构
| 组件类型 | 职责 | 实现类 |
|---|---|---|
| 应用入口 | 初始化应用,设置主题 | FlutterUnitDemoApp |
| 主页面 | 管理底部导航,切换不同页面 | HomePage |
| 启动页面 | 展示应用标志和品牌信息 | SplashScreen |
| 组件列表页面 | 展示 Flutter 组件卡片 | ComponentListScreen |
| 组件卡片 | 展示单个组件的信息 | ComponentCard |
3.3 状态管理
应用使用 Flutter 内置的 setState 进行状态管理,适用于中小型应用。主要状态包括:
- 当前选中的导航项
- 当前选中的标签栏项
- 组件列表数据
4. 关键代码解析
4.1 应用入口
dart
import 'package:flutter/material.dart';
void main() {
runApp(const FlutterUnitDemoApp());
}
class FlutterUnitDemoApp extends StatelessWidget {
const FlutterUnitDemoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FlutterUnit',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
这是应用的入口代码,创建了一个 MaterialApp 实例,并设置了主题和首页。使用了 Material 3 设计系统,提供了现代化的 UI 风格。
4.2 主页面与底部导航
dart
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _selectedIndex = 0;
static const List<Widget> _widgetOptions = <Widget>[
SplashScreen(),
ComponentListScreen(),
ComponentListScreen(), // 暂时使用同一个页面,实际应该是收藏页面
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: '搜索',
),
BottomNavigationBarItem(
icon: Icon(Icons.star),
label: '收藏',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue[600],
unselectedItemColor: Colors.grey,
onTap: _onItemTapped,
),
);
}
}
主页面实现了底部导航栏,包含三个导航项,分别对应首页、搜索和收藏页面。通过 setState 管理当前选中的导航项,并根据选中的索引显示对应的页面。
4.3 启动页面
dart
class SplashScreen extends StatelessWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.lightBlue[50],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Flutter Unit 标志
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 20,
height: 40,
color: Colors.blue,
transform: Matrix4.rotationZ(0.3),
),
const SizedBox(width: 8),
Container(
width: 20,
height: 40,
color: Colors.blue,
transform: Matrix4.rotationZ(-0.3),
),
],
),
const SizedBox(height: 40),
// 彩色圆形图案
Stack(
alignment: Alignment.center,
children: [
SizedBox(
width: 200,
height: 200,
child: CustomPaint(
painter: _ColorWheelPainter(),
),
),
// 中心圆形
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
border: Border.all(color: Colors.blue, width: 2),
),
child: const Center(
child: Text(
'F',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
),
],
),
const SizedBox(height: 40),
// Flutter Unit 文字
const Text(
'Flutter Unit',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
const SizedBox(height: 10),
const Text(
'Power By 张风捷特烈',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
),
],
),
);
}
}
启动页面实现了应用的标志和品牌信息,包括:
- Flutter Unit 标志,使用两个旋转的蓝色矩形
- 彩色圆形图案,使用 CustomPaint 绘制
- 中心圆形,带有字母 'F'
- Flutter Unit 文字和作者信息
4.4 彩色圆形图案绘制器
dart
class _ColorWheelPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = size.width / 2;
// 绘制四个扇形
final paint1 = Paint()..color = Colors.red;
final paint2 = Paint()..color = Colors.blue;
final paint3 = Paint()..color = Colors.yellow;
final paint4 = Paint()..color = Colors.green;
// 红色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
-3 * 3.14159265359 / 4,
3.14159265359 / 2,
true,
paint1,
);
// 蓝色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
-3.14159265359 / 4,
3.14159265359 / 2,
true,
paint2,
);
// 黄色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
3.14159265359 / 4,
3.14159265359 / 2,
true,
paint3,
);
// 绿色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
5 * 3.14159265359 / 4,
3.14159265359 / 2,
true,
paint4,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
彩色圆形图案绘制器使用 CustomPaint 实现,绘制了四个不同颜色的扇形,形成一个彩色的圆形图案。
4.5 组件列表页面
dart
class ComponentListScreen extends StatefulWidget {
const ComponentListScreen({super.key});
@override
State<ComponentListScreen> createState() => _ComponentListScreenState();
}
class _ComponentListScreenState extends State<ComponentListScreen> {
int _selectedTabIndex = 0;
final List<String> _tabs = [
'Blue',
'Stful',
'Row',
'Column',
'Silver',
'Other',
];
final List<ComponentCard> _components = [
ComponentCard(
title: 'Expanded',
description: '父类是Flexible,相当于一个类型为fill的flexible组件。可容纳孩子到...',
rating: 5,
color: Colors.blue[200]!,
icon: 'Ex',
),
// 其他组件...
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('FlutterUnit'),
backgroundColor: Colors.blue[600],
),
body: Column(
children: [
// 标签栏
Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 10),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
_tabs.length,
(index) => GestureDetector(
onTap: () {
setState(() {
_selectedTabIndex = index;
});
},
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
color: _selectedTabIndex == index
? Colors.blue[600]
: Colors.grey[200],
borderRadius: BorderRadius.circular(16),
),
child: Text(
_tabs[index],
style: TextStyle(
color: _selectedTabIndex == index
? Colors.white
: Colors.grey[700],
fontWeight: _selectedTabIndex == index
? FontWeight.bold
: FontWeight.normal,
),
),
),
),
),
),
),
),
// 组件列表
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 0.75,
),
itemCount: _components.length,
itemBuilder: (context, index) {
final component = _components[index];
return _buildComponentCard(component);
},
),
),
],
),
);
}
Widget _buildComponentCard(ComponentCard component) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 组件图标和名称
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: component.color,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
component.icon,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: Text(
component.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
const SizedBox(height: 10),
// 组件描述
Text(
component.description,
style: const TextStyle(
fontSize: 14,
color: Colors.grey,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 10),
// 星级评分
Row(
children: List.generate(
5,
(index) => Icon(
index < component.rating
? Icons.star
: Icons.star_border,
size: 14,
color: Colors.amber,
),
),
),
],
),
),
);
}
}
组件列表页面实现了:
- 蓝色的应用栏,显示 "FlutterUnit" 标题
- 可横向滚动的标签栏,包含不同类型的组件分类
- 网格布局的组件卡片,每个卡片包含组件图标、名称、描述和星级评分
4.6 组件卡片数据类
dart
class ComponentCard {
final String title;
final String description;
final int rating;
final Color color;
final String icon;
ComponentCard({
required this.title,
required this.description,
required this.rating,
required this.color,
required this.icon,
});
}
组件卡片数据类定义了组件卡片的属性,包括标题、描述、评分、颜色和图标。
5. 技术亮点与创新
5.1 UI 还原度
- 高度还原:成功还原了 FlutterUnit 应用的核心 UI 效果,包括启动页面、组件列表页面和底部导航栏
- 细节处理:精心处理了应用标志、彩色圆形图案、组件卡片等细节,确保视觉效果与原应用一致
- 响应式设计:使用了响应式布局,确保应用在不同屏幕尺寸上都能正常显示
5.2 技术实现
- 自定义绘制:使用 CustomPaint 实现了彩色圆形图案的绘制,展示了 Flutter 的自定义绘制能力
- 布局优化:使用 GridView 实现了组件卡片的网格布局,提高了页面的加载和滚动性能
- 状态管理:使用 setState 进行状态管理,代码简洁易懂,适合中小型应用
5.3 鸿蒙平台适配
- 兼容性:确保应用在鸿蒙平台上的正常运行,所有组件都能正确显示和交互
- 性能优化:针对鸿蒙平台的特性进行了性能优化,确保应用运行流畅
- 用户体验:保持了与原应用一致的用户体验,确保用户可以无缝切换使用
5.4 用户交互
- 标签栏交互:实现了标签栏的点击切换功能,用户可以方便地浏览不同类型的组件
- 底部导航:实现了底部导航栏的切换功能,用户可以在不同页面之间切换
- 组件卡片:设计了美观的组件卡片,提供了清晰的组件信息展示
6. 应用场景与扩展
6.1 应用场景
- 学习工具:帮助 Flutter 开发者快速了解和学习各种组件的使用方法
- 参考手册:作为 Flutter 组件的参考手册,随时查阅组件的用法和效果
- 教学演示:在 Flutter 教学中作为演示工具,展示组件的使用方法和效果
- 设计参考:作为 UI 设计的参考,了解如何构建美观的 Flutter 应用
6.2 扩展方向
- 更多组件:添加更多 Flutter 组件的演示,包括动画组件、自定义组件等
- 组件详情:添加组件详情页面,提供更详细的组件使用方法和代码示例
- 搜索功能:添加组件搜索功能,方便用户快速找到需要的组件
- 收藏功能:实现真正的收藏页面,允许用户收藏常用组件
- 代码导出:添加代码导出功能,用户可以直接复制组件的代码到自己的项目中
7. 代码优化建议
7.1 性能优化
- 使用 const 构造函数:对于不变的组件,使用 const 构造函数可以减少不必要的重建
- 使用 const 变量:对于不变的变量,使用 const 关键字可以提高性能
- 避免不必要的 setState:只在必要时调用 setState,避免过度更新
- 使用 ListView.builder:对于长列表,使用 ListView.builder 可以提高性能
- 使用 RepaintBoundary:对于复杂的组件,使用 RepaintBoundary 可以减少重绘范围
7.2 代码结构优化
- 组件拆分:将大组件拆分为小组件,提高代码的可读性和可维护性
- 提取常量:将重复使用的值提取为常量,便于统一管理和修改
- 使用命名参数:使用命名参数可以提高代码的可读性
- 添加注释:为关键代码添加注释,提高代码的可维护性
- 使用枚举:对于有限的选项,使用枚举可以提高代码的可读性和类型安全性
7.3 用户体验优化
- 添加过渡动画:在页面切换和状态变化时添加过渡动画,提高用户体验
- 添加加载状态:在加载数据时添加加载状态,提高用户体验
- 添加错误处理:添加错误处理,确保应用在遇到错误时能够优雅地处理
- 添加空状态:添加空状态提示,提高用户体验
- 添加手势反馈:为可交互组件添加手势反馈,提高用户体验
7.4 功能优化
- 添加组件分类:进一步细化组件分类,便于用户查找
- 添加组件搜索:添加组件搜索功能,方便用户快速找到需要的组件
- 添加代码复制:添加代码复制功能,方便用户复制组件代码
- 添加组件收藏:添加组件收藏功能,方便用户保存常用组件
- 添加组件评论:添加组件评论功能,方便用户交流和分享使用经验
8. 测试与调试
8.1 测试策略
- 单元测试:对关键函数和方法进行单元测试,确保其功能正确
- Widget 测试:对关键组件进行 Widget 测试,确保其显示和交互正确
- 集成测试:对整个应用进行集成测试,确保各组件之间的交互正确
- 性能测试:对应用进行性能测试,确保其性能符合要求
- 跨平台测试:在不同平台上测试应用,确保其在所有平台上的表现一致
8.2 调试技巧
- 使用 print 语句:在关键位置添加 print 语句,输出变量值和执行流程
- 使用 Flutter DevTools:使用 Flutter DevTools 进行调试,查看应用的布局、性能和状态
- 使用断点:在关键位置设置断点,查看变量值和执行流程
- 使用热重载:使用热重载功能,快速查看代码修改的效果
- 使用模拟器:在不同的模拟器上测试应用,确保其在不同设备上的表现一致
8.3 常见问题及解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 布局溢出 | 组件尺寸超过屏幕尺寸 | 使用 SingleChildScrollView 包裹内容,或使用 Expanded 组件 |
| 状态更新不及时 | setState 调用时机不正确 | 确保在正确的时机调用 setState,避免在 build 方法中调用 |
| 性能问题 | 组件重建过于频繁 | 使用 const 构造函数,避免不必要的 setState,使用 ListView.builder 等高效组件 |
| 导航错误 | 导航逻辑不正确 | 确保导航逻辑正确,使用正确的导航方法 |
| 跨平台兼容性问题 | 平台差异 | 使用 Flutter 内置的跨平台组件,避免使用平台特定的 API |
| 图片资源错误 | 图片资源不存在 | 使用默认资源或占位符,确保应用在缺少资源时仍能正常运行 |
9. 总结与展望
9.1 项目成果
FlutterUnit 组件百科适配项目成功实现了以下功能:
- 高度还原了 FlutterUnit 应用的核心 UI 效果,包括启动页面、组件列表页面和底部导航栏
- 实现了组件卡片的网格布局,展示了多个 Flutter 组件的信息
- 确保了应用在鸿蒙平台上的正常运行,所有组件都能正确显示和交互
- 提供了清晰的组件信息展示,包括组件名称、描述和星级评分
- 实现了标签栏和底部导航栏的交互功能,提高了用户体验
9.2 技术价值
- 学习价值:为 Flutter 开发者提供了一个学习组件使用方法的平台
- 参考价值:作为 Flutter 组件的参考手册,随时查阅组件的用法和效果
- 教学价值:在 Flutter 教学中作为演示工具,展示组件的使用方法和效果
- 开发价值:为开发者提供了组件使用的最佳实践,加速开发过程
- 适配价值:展示了如何将 Flutter 应用适配到鸿蒙平台,为跨平台开发提供参考
9.3 未来展望
- 扩展组件库:添加更多 Flutter 组件的演示,包括动画组件、自定义组件等
- 增强功能:添加组件详情页面、搜索功能、收藏功能等增强功能
- 优化性能:进一步优化应用性能,提高用户体验
- 社区贡献:将项目开源,邀请社区贡献,共同完善和扩展项目
- 多平台支持:确保在更多平台上的兼容性,包括鸿蒙、iOS、Android、Web 等
- 国际化:添加多语言支持,使应用能够服务于更多用户
9.4 结语
FlutterUnit 组件百科适配项目是一个功能完整、界面美观、交互友好的组件百科全书,为 Flutter 开发者提供了一个学习和参考的平台。通过本项目,开发者可以快速了解和掌握 Flutter 中各种组件的使用方法,提高开发效率和代码质量。
同时,本项目也展示了如何将 Flutter 应用适配到鸿蒙平台,为跨平台开发提供了参考。未来,我们将继续完善和扩展项目,添加更多组件和功能,为 Flutter 社区做出更大的贡献。
10. 附录
10.1 完整代码
dart
import 'package:flutter/material.dart';
void main() {
runApp(const FlutterUnitDemoApp());
}
class FlutterUnitDemoApp extends StatelessWidget {
const FlutterUnitDemoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FlutterUnit',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _selectedIndex = 0;
static const List<Widget> _widgetOptions = <Widget>[
SplashScreen(),
ComponentListScreen(),
ComponentListScreen(), // 暂时使用同一个页面,实际应该是收藏页面
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: '搜索',
),
BottomNavigationBarItem(
icon: Icon(Icons.star),
label: '收藏',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue[600],
unselectedItemColor: Colors.grey,
onTap: _onItemTapped,
),
);
}
}
// 启动页面
class SplashScreen extends StatelessWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.lightBlue[50],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Flutter Unit 标志
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 20,
height: 40,
color: Colors.blue,
transform: Matrix4.rotationZ(0.3),
),
const SizedBox(width: 8),
Container(
width: 20,
height: 40,
color: Colors.blue,
transform: Matrix4.rotationZ(-0.3),
),
],
),
const SizedBox(height: 40),
// 彩色圆形图案
Stack(
alignment: Alignment.center,
children: [
SizedBox(
width: 200,
height: 200,
child: CustomPaint(
painter: _ColorWheelPainter(),
),
),
// 中心圆形
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
border: Border.all(color: Colors.blue, width: 2),
),
child: const Center(
child: Text(
'F',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
),
],
),
const SizedBox(height: 40),
// Flutter Unit 文字
const Text(
'Flutter Unit',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
const SizedBox(height: 10),
const Text(
'Power By 张风捷特烈',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
),
],
),
);
}
}
// 彩色圆形图案绘制器
class _ColorWheelPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = size.width / 2;
// 绘制四个扇形
final paint1 = Paint()..color = Colors.red;
final paint2 = Paint()..color = Colors.blue;
final paint3 = Paint()..color = Colors.yellow;
final paint4 = Paint()..color = Colors.green;
// 红色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
-3 * 3.14159265359 / 4,
3.14159265359 / 2,
true,
paint1,
);
// 蓝色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
-3.14159265359 / 4,
3.14159265359 / 2,
true,
paint2,
);
// 黄色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
3.14159265359 / 4,
3.14159265359 / 2,
true,
paint3,
);
// 绿色扇形
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
5 * 3.14159265359 / 4,
3.14159265359 / 2,
true,
paint4,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
// 组件列表页面
class ComponentListScreen extends StatefulWidget {
const ComponentListScreen({super.key});
@override
State<ComponentListScreen> createState() => _ComponentListScreenState();
}
class _ComponentListScreenState extends State<ComponentListScreen> {
int _selectedTabIndex = 0;
final List<String> _tabs = [
'Blue',
'Stful',
'Row',
'Column',
'Silver',
'Other',
];
final List<ComponentCard> _components = [
ComponentCard(
title: 'Expanded',
description: '父类是Flexible,相当于一个类型为fill的flexible组件。可容纳孩子到...',
rating: 5,
color: Colors.blue[200]!,
icon: 'Ex',
),
ComponentCard(
title: 'MediaQuery',
description: '可通过MediaQuery的某个获取屏幕尺寸、设备密度、文字缩放比例、边距...',
rating: 4,
color: Colors.green[200]!,
icon: 'Me',
),
ComponentCard(
title: 'Positioned',
description: '只能用于Stack中,可以指定左上右下的距离来对单个组件进行位置精确定位。',
rating: 4,
color: Colors.orange[200]!,
icon: 'Po',
),
ComponentCard(
title: 'Flexible',
description: '只能用于只能用于Row、Column和Flexible布局中,可使孩子利用剩余空间。',
rating: 4,
color: Colors.purple[200]!,
icon: 'Fl',
),
ComponentCard(
title: 'ScrollConfiguration',
description: '需要包裹一个可滑动的组件,并通过behavior属性控制滑动时的效果,可以...',
rating: 4,
color: Colors.yellow[200]!,
icon: 'Sc',
),
ComponentCard(
title: 'Transform',
description: '可容纳一个子组件,可以通过一个4x4的变换矩阵对子组件进行变换。',
rating: 5,
color: Colors.purple[200]!,
icon: 'Tr',
),
ComponentCard(
title: 'OverflowBox',
description: '可容纳一个子组件,且子组件允许溢出父组件区域,可以指定宽高的最大...',
rating: 4,
color: Colors.blue[200]!,
icon: 'Ov',
),
ComponentCard(
title: 'FittedBox',
description: '可容纳一个子组件,使用fit属性决定子组件区域相当于父组件的适应模式。',
rating: 4,
color: Colors.green[200]!,
icon: 'Fi',
),
ComponentCard(
title: 'ShaderMask',
description: '可容纳一个孩子,并通过着色器来对孩子进行着色,可指定着色模式,通...',
rating: 4,
color: Colors.orange[200]!,
icon: 'Sh',
),
ComponentCard(
title: 'BackdropFilter',
description: '可容纳一个孩子,并将背景进行模糊处理,可以指定模糊的程度和模式...',
rating: 4,
color: Colors.purple[200]!,
icon: 'Ba',
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('FlutterUnit'),
backgroundColor: Colors.blue[600],
),
body: Column(
children: [
// 标签栏
Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 10),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
_tabs.length,
(index) => GestureDetector(
onTap: () {
setState(() {
_selectedTabIndex = index;
});
},
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
color: _selectedTabIndex == index
? Colors.blue[600]
: Colors.grey[200],
borderRadius: BorderRadius.circular(16),
),
child: Text(
_tabs[index],
style: TextStyle(
color: _selectedTabIndex == index
? Colors.white
: Colors.grey[700],
fontWeight: _selectedTabIndex == index
? FontWeight.bold
: FontWeight.normal,
),
),
),
),
),
),
),
),
// 组件列表
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 0.75,
),
itemCount: _components.length,
itemBuilder: (context, index) {
final component = _components[index];
return _buildComponentCard(component);
},
),
),
],
),
);
}
Widget _buildComponentCard(ComponentCard component) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 组件图标和名称
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: component.color,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
component.icon,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: Text(
component.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
const SizedBox(height: 10),
// 组件描述
Text(
component.description,
style: const TextStyle(
fontSize: 14,
color: Colors.grey,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 10),
// 星级评分
Row(
children: List.generate(
5,
(index) => Icon(
index < component.rating
? Icons.star
: Icons.star_border,
size: 14,
color: Colors.amber,
),
),
),
],
),
),
);
}
}
// 组件卡片数据类
class ComponentCard {
final String title;
final String description;
final int rating;
final Color color;
final String icon;
ComponentCard({
required this.title,
required this.description,
required this.rating,
required this.color,
required this.icon,
});
}
10.2 依赖项
| 依赖项 | 版本 | 用途 |
|---|---|---|
| flutter | 3.35.7 | 核心框架 |
| material.dart | - | Material 设计组件库 |
10.3 运行环境
| 环境 | 版本 |
|---|---|
| Flutter | 3.35.7 |
| Dart | 3.2.0 |
| 鸿蒙 SDK | 5.0.0 |
| Android SDK | 33.0.0 |
| iOS SDK | 16.0 |