Flutter for OpenHarmony 猫咪管家App实战:猫咪详情页面开发
本文介绍了猫咪详情页的设计实现,通过四个核心区块展示信息:渐变头部突出视觉焦点,基本信息卡片展示关键数据,快捷操作提供常用功能入口,健康摘要呈现重要指标。采用模块化组件设计,信息行统一封装,可选字段条件渲染,确保界面整洁有序。代码示例展示了参数传递、布局结构、样式处理和交互逻辑,实现了功能完备且视觉友好的详情页设计。

猫咪详情页是信息展示的核心,用户点进来能看到这只猫的所有信息。这篇来聊聊如何设计一个信息丰富又不杂乱的详情页。
一、页面接收参数
详情页需要接收猫咪数据:
class CatDetailScreen extends StatelessWidget {
final CatModel cat;
const CatDetailScreen({super.key, required this.cat});
用
required标记必传参数,编译器会检查。
数据从上一个页面传过来,不需要再从 Provider 读取。
页面结构:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(cat.name),
),
body: SingleChildScrollView(
child: Column(
children: [
_buildHeader(context),
_buildInfoSection(context),
_buildQuickActions(context),
_buildHealthSummary(context),
],
),
),
);
}
AppBar 标题直接用猫咪名字,简洁明了。
四个区块垂直排列,用SingleChildScrollView支持滚动。
二、头部渐变区域
头部用渐变背景突出视觉效果:
Widget _buildHeader(BuildContext context) {
return Container(
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.orange, Colors.orange.shade300],
),
),
LinearGradient从上到下渐变,颜色由深变浅。
和 AppBar 的橙色衔接自然,视觉上是一体的。
头像居中显示:
child: Column(
children: [
CircleAvatar(
radius: 50.r,
backgroundColor: Colors.white,
child: Icon(Icons.pets, size: 50.sp, color: Colors.orange),
),
白色背景的头像在橙色渐变上很醒目。
后续可以换成真实照片。
名字和基本信息:
SizedBox(height: 16.h),
Text(
cat.name,
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
名字用大号粗体,是整个头部的视觉焦点。
白色文字在橙色背景上对比度高。
性别和品种:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
cat.gender == '公' ? Icons.male : Icons.female,
color: Colors.white,
size: 20.sp,
),
SizedBox(width: 8.w),
Text(
'${cat.breed} · ${cat.ageString}',
style: TextStyle(
fontSize: 16.sp,
color: Colors.white.withOpacity(0.9),
),
),
],
),
性别图标加品种和年龄,一行展示关键信息。
透明度 0.9 让次要信息稍微弱化。
三、基本信息卡片
信息区用 Card 包裹:
Widget _buildInfoSection(BuildContext context) {
return Card(
margin: EdgeInsets.all(16.w),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'基本信息',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
Card 自带圆角和阴影,不用额外设置。
标题加粗,和内容区分开。
信息行列表:
SizedBox(height: 16.h),
_buildInfoRow('品种', cat.breed),
_buildInfoRow('性别', cat.gender),
_buildInfoRow('出生日期', DateFormat('yyyy-MM-dd').format(cat.birthDate)),
_buildInfoRow('年龄', cat.ageString),
_buildInfoRow('体重', '${cat.weight} kg'),
_buildInfoRow('绝育状态', cat.isNeutered ? '已绝育' : '未绝育'),
每行一个信息,用统一的组件渲染。
日期用DateFormat格式化,更易读。
可选字段条件渲染:
if (cat.microchipId != null && cat.microchipId!.isNotEmpty)
_buildInfoRow('芯片号', cat.microchipId!),
if (cat.notes != null && cat.notes!.isNotEmpty)
_buildInfoRow('备注', cat.notes!),
芯片号和备注是选填的,有值才显示。
双重判断:不为 null 且不为空字符串。
四、信息行组件
抽取通用的信息行:
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 80.w,
child: Text(
label,
style: TextStyle(color: Colors.grey[600], fontSize: 14.sp),
),
),
标签固定宽度 80,保证对齐。
crossAxisAlignment.start让多行文本顶部对齐。
值的展示:
Expanded(
child: Text(
value,
style: TextStyle(fontSize: 14.sp),
),
),
Expanded让值占满剩余空间。
长文本会自动换行,不会溢出。
五、快捷操作区
四个功能入口:
Widget _buildQuickActions(BuildContext context) {
return Card(
margin: EdgeInsets.symmetric(horizontal: 16.w),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'快捷操作',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
和首页的快捷操作类似,但功能不同。
这里是针对当前猫咪的操作。
操作按钮行:
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildActionItem(
context,
Icons.restaurant,
'喂食记录',
Colors.green,
() => Navigator.push(context, MaterialPageRoute(
builder: (_) => FeedingListScreen(catId: cat.id),
)),
),
喂食记录用绿色,和食物相关。
跳转时传入cat.id,只显示这只猫的记录。
其他操作:
_buildActionItem(
context,
Icons.monitor_weight,
'体重记录',
Colors.blue,
() => Navigator.push(context, MaterialPageRoute(
builder: (_) => WeightChartScreen(catId: cat.id),
)),
),
_buildActionItem(
context,
Icons.timeline,
'成长记录',
Colors.purple,
() => Navigator.push(context, MaterialPageRoute(
builder: (_) => GrowthMilestoneScreen(cat: cat),
)),
),
_buildActionItem(
context,
Icons.medical_services,
'健康记录',
Colors.red,
() => Navigator.push(context, MaterialPageRoute(
builder: (_) => HealthRecordListScreen(catId: cat.id),
)),
),
四种颜色区分四个功能,一目了然。
健康记录用红色,暗示重要性。
六、操作按钮组件
按钮的通用实现:
Widget _buildActionItem(
BuildContext context,
IconData icon,
String label,
Color color,
VoidCallback onTap,
) {
return GestureDetector(
onTap: onTap,
child: Column(
children: [
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(icon, color: color, size: 28.sp),
),
背景用主色的 10% 透明度,淡雅不刺眼。
圆角 12 和其他卡片保持一致。
标签文字:
SizedBox(height: 8.h),
Text(
label,
style: TextStyle(fontSize: 12.sp, color: Colors.grey[700]),
),
字号小一点,不抢图标的风头。
灰色文字作为辅助说明。
七、健康概况区
这个区块需要从 HealthProvider 读取数据:
Widget _buildHealthSummary(BuildContext context) {
return Consumer<HealthProvider>(
builder: (context, healthProvider, child) {
final latestVaccination = healthProvider.getLatestVaccination(cat.id);
final latestDeworming = healthProvider.getLatestDeworming(cat.id);
用
Consumer监听健康数据变化。
获取最近一次疫苗和驱虫记录。
卡片结构:
return Card(
margin: EdgeInsets.all(16.w),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'健康概况',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
和其他卡片样式统一。
标题用粗体突出。
疫苗信息:
_buildHealthItem(
'最近疫苗',
latestVaccination != null
? '${latestVaccination.title} (${DateFormat('yyyy-MM-dd').format(latestVaccination.date)})'
: '暂无记录',
Icons.vaccines,
Colors.blue,
),
有记录显示名称和日期,没有显示"暂无记录"。
疫苗用蓝色针管图标。
驱虫信息:
SizedBox(height: 12.h),
_buildHealthItem(
'最近驱虫',
latestDeworming != null
? '${latestDeworming.title} (${DateFormat('yyyy-MM-dd').format(latestDeworming.date)})'
: '暂无记录',
Icons.bug_report,
Colors.green,
),
驱虫用绿色虫子图标,形象直观。
两条信息之间留 12 的间距。
八、健康项组件
健康信息的通用展示:
Widget _buildHealthItem(String title, String value, IconData icon, Color color) {
return Row(
children: [
Container(
padding: EdgeInsets.all(8.w),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(8.r),
),
child: Icon(icon, color: color, size: 20.sp),
),
图标放在小方块里,视觉上更整齐。
圆角 8 比操作按钮的 12 小一点,层次分明。
文字部分:
SizedBox(width: 12.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(fontSize: 12.sp, color: Colors.grey[600]),
),
Text(
value,
style: TextStyle(fontSize: 14.sp),
),
],
),
),
标题小字灰色,值正常大小黑色。
上下两行,信息层次清晰。
九、设计思路总结
详情页的设计遵循几个原则:
信息分组:把相关信息放在同一个卡片里,用户扫一眼就能找到想要的。
视觉层次:头部用渐变背景突出,卡片用阴影区分,标题用粗体强调。
操作便捷:常用功能放在快捷操作区,一键直达。
数据联动:健康概况从 Provider 实时读取,数据更新后自动刷新。
小结
详情页是信息展示的集大成者,要在有限的空间里展示尽可能多的信息,同时保持界面整洁。渐变背景、卡片分组、图标配色这些细节都会影响用户体验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)