在开发健康管理类App时,目标选择页面是整个用户体验流程中的关键起点。这个看似简单的页面实际上承担着重要的功能定位和用户体验考量。
目标选择页面需要实现三个核心功能选项:减重、增重和保持体重。这三个选项不是随意排列的,而是基于健康管理领域最常见的用户需求划分。从业务逻辑来看,用户的选择将直接影响后续的:
例如,选择"减重"的用户,系统会自动为其设置热量缺口(通常为每日总消耗的10-20%);而选择"增重"的用户则会获得热量盈余方案。这种差异化的处理需要在架构设计时就考虑进去。
在设计这个页面时,我们遵循了几个关键的用户体验原则:
我们采用StatefulWidget来管理页面状态,这是经过多方面考量后的选择:
dart复制class GoalPage extends StatefulWidget {
const GoalPage({super.key});
@override
State<GoalPage> createState() => _GoalPageState();
}
使用StatefulWidget而非StatelessWidget的原因包括:
对于状态变量的设计,我们特别使用了可空类型int?而不是传统的-1表示未选择。这是现代Dart开发的最佳实践,能更清晰地表达设计意图。
页面中的动画效果主要分为两个层次:
dart复制AnimatedContainer(
duration: const Duration(milliseconds: 200),
// 其他属性...
)
使用AnimatedContainer实现属性变化的自动过渡动画,包括:
dart复制PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 400),
transitionsBuilder: (_, animation, __, child) {
return FadeTransition(opacity: animation, child: child);
},
)
我们自定义了淡入效果替代默认的滑动效果,因为从目标选择到个人信息属于"确认"流程而非层级导航。
页面布局采用了多种响应式设计技术:
dart复制body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Column(
children: [
const Spacer(flex: 2),
// 标题部分
const Spacer(flex: 2),
// 按钮列表
const Spacer(flex: 3),
// 底部登录入口
],
),
),
)
关键技术点:
我们为健康管理App设计了专门的色彩系统:
dart复制final gradients = [
[Color(0xFF7DD8C7), Color(0xFF4ECDC4)], // 浅绿
[Color(0xFF4ECDC4), Color(0xFF2E9E8F)], // 中绿
[Color(0xFF2E9E8F), Color(0xFF1A7A6C)], // 深绿
];
色彩选择基于以下考虑:
按钮的交互状态机包含以下状态:
默认状态:
选中状态:
点击状态(通过GestureDetector的onTapDown/onTapUp实现):
这种设计创造了令人满意的触觉反馈,符合Material Design的触觉反馈准则。
我们采取了多项措施确保页面流畅运行:
避免不必要的重建:
动画性能优化:
图片资源优化:
健壮的错误处理是生产级应用的关键:
dart复制Future.delayed(const Duration(milliseconds: 300), () {
if (mounted) {
// 跳转逻辑
}
});
我们处理了以下边界情况:
我们为这个页面设计了全面的测试用例:
dart复制void main() {
testWidgets('GoalPage UI测试', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: GoalPage()));
// 验证初始状态
expect(find.text('What\'s your goal?'), findsOneWidget);
expect(find.byType(_GoalButton), findsNWidgets(3));
// 模拟用户交互
await tester.tap(find.text('Lose weight'));
await tester.pump();
// 验证状态变化
// ...
});
}
测试覆盖以下方面:
在完整的App流程中测试目标选择页面:
我们采用清晰的项目结构:
code复制lib/
features/
onboarding/
presentation/
widgets/
goal_button.dart
goal_page.dart
domain/
entities/
user_goal.dart
application/
goal_selection_bloc.dart
这种结构遵循了Clean Architecture原则,使得:
虽然当前只有英文文本,但我们已做好国际化准备:
dart复制Text(
S.of(context).whatsYourGoal,
style: Theme.of(context).textTheme.headlineMedium,
)
使用arb文件管理多语言资源,便于后期扩展其他语言支持。
在实现这个页面的过程中,我们积累了几个关键经验:
动画时序的重要性:
状态管理的边界:
用户体验的微妙平衡:
性能优化的实际效果:
这个目标选择页面虽然看起来简单,但融合了Flutter开发的诸多最佳实践。从状态管理到动画实现,从性能优化到异常处理,每个细节都影响着最终的用户体验。在实际项目中,我们需要在开发效率和质量要求之间找到平衡,既要快速迭代,又要保证代码的可维护性和扩展性