#请添加图片描述

前言

心率是反映心脏健康状况的重要指标,静息心率、运动心率、最大心率等数据都能帮助用户了解自己的心血管健康水平。心率详情页面需要展示当前心率、统计数据以及历史记录。

这篇文章会详细讲解心率详情页面的实现,包括心率展示卡片、统计数据卡片、历史记录列表等核心组件的开发过程。


页面整体结构

心率详情页面包含三个主要部分:当前心率卡片、统计数据卡片、历史记录列表。

class HeartRateDetailPage extends StatelessWidget {
  const HeartRateDetailPage({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFFAFAFC),
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios_rounded, size: 20.w), 
          onPressed: () => Get.back()
        ),
        title: Text('心率详情', style: TextStyle(fontSize: 17.sp, fontWeight: FontWeight.w600)),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(20.w),
        child: Column(
          children: [
            _buildCurrentCard(),
            SizedBox(height: 20.h),
            _buildStatsCard(),
            SizedBox(height: 20.h),
            _buildHistory(),
          ],
        ),
      ),
    );
  }
}

页面结构清晰,三个卡片垂直排列,用 SizedBox(height: 20.h) 控制间距。这个间距值在整个应用中保持一致,让页面看起来更协调。


当前心率展示卡片

心率卡片使用暖红色渐变背景,这个颜色和心脏、心率的主题非常契合。卡片顶部放一个心形图标,增强视觉识别度。

Widget _buildCurrentCard() {
  return Container(
    width: double.infinity,
    padding: EdgeInsets.all(24.w),
    decoration: BoxDecoration(
      gradient: const LinearGradient(
        colors: [Color(0xFFFF8066), Color(0xFFFF9F8A)]
      ),
      borderRadius: BorderRadius.circular(24.r),
    ),
    child: Column(
      children: [
        Icon(Icons.favorite, size: 40.w, color: Colors.white70),
        SizedBox(height: 8.h),
        Text('当前心率', style: TextStyle(fontSize: 13.sp, color: Colors.white70)),
        SizedBox(height: 4.h),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Text('72', style: TextStyle(
              fontSize: 56.sp, 
              fontWeight: FontWeight.w700, 
              color: Colors.white
            )),
            Padding(
              padding: EdgeInsets.only(bottom: 10.h), 
              child: Text(' bpm', style: TextStyle(
                fontSize: 18.sp, 
                color: Colors.white70
              ))
            ),
          ],
        ),
        Container(
          padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h),
          decoration: BoxDecoration(
            color: Colors.white.withOpacity(0.2), 
            borderRadius: BorderRadius.circular(20.r)
          ),
          child: Text('正常', style: TextStyle(
            fontSize: 13.sp, 
            color: Colors.white
          )),
        ),
      ],
    ),
  );
}

渐变色从 #FF8066#FF9F8A,是一个柔和的珊瑚红色系。心形图标使用 Icons.favorite,设置为 Colors.white70 稍微透明一点,不会太抢眼。

心率数值使用 56sp 的超大字号,这是整个应用中最大的数字展示。单位 bpm(beats per minute)放在右下角,用户一眼就能理解这是心率数据。


心率正常范围

成年人的静息心率正常范围一般在 60-100 bpm 之间。运动员或经常锻炼的人可能会更低一些。我们可以根据这个标准来判断心率状态:

String _getHeartRateStatus(int rate) {
  if (rate < 60) return '偏低';
  if (rate <= 100) return '正常';
  return '偏高';
}

Color _getStatusColor(String status) {
  switch (status) {
    case '偏低': return const Color(0xFF4D96FF);
    case '正常': return const Color(0xFF00C9A7);
    case '偏高': return const Color(0xFFFF6B6B);
    default: return const Color(0xFF00C9A7);
  }
}

偏低用蓝色,正常用绿色,偏高用红色。这种颜色编码符合用户的直觉认知。


统计数据卡片

统计卡片展示最低、平均、最高三个心率值,帮助用户了解自己心率的波动范围。

Widget _buildStatsCard() {
  return Container(
    padding: EdgeInsets.all(20.w),
    decoration: BoxDecoration(
      color: Colors.white, 
      borderRadius: BorderRadius.circular(20.r)
    ),
    child: Row(
      children: [
        _buildStatItem('最低', '58', 'bpm'),
        _buildStatItem('平均', '72', 'bpm'),
        _buildStatItem('最高', '98', 'bpm'),
      ],
    ),
  );
}

Widget _buildStatItem(String label, String value, String unit) {
  return Expanded(
    child: Column(
      children: [
        Text(label, style: TextStyle(fontSize: 12.sp, color: Colors.grey[500])),
        SizedBox(height: 6.h),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Text(value, style: TextStyle(
              fontSize: 24.sp, 
              fontWeight: FontWeight.w700, 
              color: const Color(0xFF1A1A2E)
            )),
            Padding(
              padding: EdgeInsets.only(bottom: 3.h), 
              child: Text(' $unit', style: TextStyle(
                fontSize: 11.sp, 
                color: Colors.grey[400]
              ))
            ),
          ],
        ),
      ],
    ),
  );
}

三个统计项用 Expanded 平均分配宽度,每个项目垂直排列标签、数值和单位。标签用灰色小字,数值用深色大字,单位用灰色小字,形成清晰的视觉层次。

这种三栏统计布局在健康类应用中很常见,用户可以快速对比最低、平均、最高三个值,了解自己心率的波动情况。


历史记录列表

历史记录展示用户过去的心率测量数据。

Widget _buildHistory() {
  final history = [
    {'date': '今天', 'time': '08:00', 'value': '72'},
    {'date': '昨天', 'time': '22:00', 'value': '68'},
    {'date': '昨天', 'time': '08:15', 'value': '75'},
    {'date': '1月9日', 'time': '08:00', 'value': '70'},
  ];

  return Container(
    padding: EdgeInsets.all(20.w),
    decoration: BoxDecoration(
      color: Colors.white, 
      borderRadius: BorderRadius.circular(20.r)
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text('历史记录', style: TextStyle(
          fontSize: 16.sp, 
          fontWeight: FontWeight.w600, 
          color: const Color(0xFF1A1A2E)
        )),
        SizedBox(height: 16.h),
        ...history.map((item) => Padding(
          padding: EdgeInsets.only(bottom: 14.h),
          child: Row(
            children: [
              Expanded(
                child: Text('${item['date']} ${item['time']}', style: TextStyle(
                  fontSize: 14.sp, 
                  color: const Color(0xFF1A1A2E)
                ))
              ),
              Text('${item['value']} bpm', style: TextStyle(
                fontSize: 15.sp, 
                fontWeight: FontWeight.w600, 
                color: const Color(0xFF1A1A2E)
              )),
            ],
          ),
        )),
      ],
    ),
  );
}

历史记录的布局比较简单,左边是日期时间,右边是心率值。不需要额外的状态标签,因为心率值本身就能说明问题。

日期时间合并显示,用空格分隔。这种方式比分两行显示更紧凑,适合列表项的展示。


心率变异性说明

除了基本的心率数值,心率变异性(HRV)也是一个重要的健康指标。HRV 反映的是心跳间隔的变化程度,较高的 HRV 通常表示更好的心血管健康状况。

虽然当前页面没有展示 HRV 数据,但在实际应用中可以考虑添加这个功能:

Widget _buildHrvCard() {
  return Container(
    padding: EdgeInsets.all(16.w),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(16.r),
    ),
    child: Row(
      children: [
        Container(
          padding: EdgeInsets.all(10.w),
          decoration: BoxDecoration(
            color: const Color(0xFF845EC2).withOpacity(0.12),
            borderRadius: BorderRadius.circular(12.r),
          ),
          child: Icon(
            Icons.show_chart_rounded, 
            size: 22.w, 
            color: const Color(0xFF845EC2)
          ),
        ),
        SizedBox(width: 14.w),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('心率变异性', style: TextStyle(
                fontSize: 14.sp, 
                fontWeight: FontWeight.w500, 
                color: const Color(0xFF1A1A2E)
              )),
              Text('反映自主神经系统健康', style: TextStyle(
                fontSize: 12.sp, 
                color: Colors.grey[400]
              )),
            ],
          ),
        ),
        Text('45 ms', style: TextStyle(
          fontSize: 16.sp, 
          fontWeight: FontWeight.w600, 
          color: const Color(0xFF845EC2)
        )),
      ],
    ),
  );
}

HRV 卡片使用紫色主题,和心率的红色形成区分。这种设计让用户能快速识别不同类型的数据。


测量时间的重要性

心率会随着时间和活动状态变化,早晨刚醒来时的静息心率最能反映真实的心血管健康状况。在历史记录中标注测量时间,可以帮助用户理解数据的含义。

Widget _buildTimeContext(String time) {
  String context = '';
  final hour = int.tryParse(time.split(':')[0]) ?? 0;
  
  if (hour >= 6 && hour < 9) {
    context = '晨起';
  } else if (hour >= 12 && hour < 14) {
    context = '午间';
  } else if (hour >= 18 && hour < 21) {
    context = '傍晚';
  } else if (hour >= 21 || hour < 6) {
    context = '夜间';
  }
  
  return Text(
    context, 
    style: TextStyle(fontSize: 11.sp, color: Colors.grey[400])
  );
}

根据测量时间自动添加上下文标签,让用户更容易理解每条记录的背景。


小结

心率详情页面通过三个层次展示数据:当前心率卡片突出显示最新数据,统计卡片展示波动范围,历史记录提供详细的追踪信息。

红色系的渐变背景和心形图标强化了心率主题的视觉识别,统计数据的三栏布局让用户能快速对比最低、平均、最高值。这些设计细节共同构成了一个专业且易用的心率监测界面。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐