1. 项目概述
最近我在开发一款基于Flutter for OpenHarmony的手语学习应用。作为应用的门面,首页设计至关重要,它需要同时承载信息展示和功能入口的双重职责。经过多次迭代,最终实现了一个既美观又实用的首页界面。
这个首页采用了模块化设计思路,将不同功能区域拆分为独立组件。整体布局使用SingleChildScrollView实现可滑动效果,确保在小屏设备上也能完整展示所有内容。界面风格上采用了Material Design规范,同时融入了一些个性化设计元素。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 跨平台框架选择
选择Flutter for OpenHarmony主要基于以下几点考虑:
- 跨平台一致性:Flutter的跨平台特性可以确保应用在OpenHarmony和其他平台上的表现一致
- 高性能渲染:Flutter的Skia引擎能提供流畅的UI体验
- 丰富的组件库:Material和Cupertino风格的组件可以快速构建美观界面
- 热重载支持:开发过程中可以实时查看修改效果
2.2 状态管理方案
项目中采用了Provider作为状态管理方案,主要优势包括:
- 响应式更新:数据变化时界面自动刷新
- 代码解耦:业务逻辑与UI分离
- 作用域控制:可以精确控制状态的作用范围
- 学习曲线平缓:相比Redux等方案更易上手
2.3 屏幕适配方案
为了适配不同尺寸的设备,使用了flutter_screenutil库:
dart复制// 初始化代码
ScreenUtil.init(
context,
designSize: const Size(360, 690),
);
使用方式:
- 宽度适配:16.w
- 高度适配:16.h
- 字体适配:16.sp
- 圆角适配:16.r
这种方案相比传统的MediaQuery更加简洁直观。
3. 核心组件实现
3.1 欢迎卡片组件
欢迎卡片是用户进入应用后看到的第一个元素,设计上需要突出亲切感和成就感。
dart复制Widget _buildWelcomeCard(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
return Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF00897B), Color(0xFF4DB6AC)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16.r),
),
child: Row(
children: [
CircleAvatar(
radius: 30.r,
backgroundColor: Colors.white,
child: Icon(
Icons.person,
size: 35.sp,
color: const Color(0xFF00897B)
),
),
SizedBox(width: 16.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'你好,${userProvider.userName}',
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.bold,
color: Colors.white
),
),
Text(
'已连续学习 ${userProvider.consecutiveDays} 天',
style: TextStyle(fontSize: 14.sp, color: Colors.white70),
),
],
),
),
],
),
);
}
设计要点:
- 使用渐变背景提升视觉层次感
- 圆形头像采用白色背景+主题色图标,形成对比
- 文字信息左对齐,符合阅读习惯
- 次要信息使用透明度降低的白色,保持界面整洁
3.2 学习进度组件
学习进度展示采用卡片式设计,包含进度条和详细数据。
dart复制Widget _buildDailyProgress(BuildContext context) {
final appProvider = Provider.of<AppProvider>(context);
final progress = appProvider.todayLearned / appProvider.dailyGoal;
return GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(build
