在这里插入图片描述
在开发家庭药箱管理应用时,首页的设计至关重要。它是用户打开应用后看到的第一个界面。今天我们就来详细讲解如何使用Flutter for OpenHarmony实现一个功能完善的首页。

首页的设计思路

一个好的药箱管理应用首页应该包含:快捷功能入口药品状态提醒今日用药计划以及家庭成员概览。这样的设计能让用户一眼就看到最重要的信息。

页面整体结构搭建

首先我们来看首页的基本框架代码:

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('家庭药箱管理'),
        actions: [
          IconButton(
            icon: const Icon(Icons.notifications_outlined),
            onPressed: () => Get.to(() => const TodayReminderScreen()),
          ),
        ],
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16.w),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildQuickActions(context),
            SizedBox(height: 20.h),
            _buildAlertSection(context),
            SizedBox(height: 20.h),
            _buildTodayReminders(context),
            SizedBox(height: 20.h),
            _buildFamilySection(context),
          ],
        ),
      ),
    );
  }
}

使用SingleChildScrollView包裹整个内容区域,因为首页包含多个功能模块,内容可能会超出屏幕高度。AppBar右侧放置了通知图标,点击后跳转到今日用药提醒页面。

快捷功能区的实现

快捷功能区是用户最常用的操作入口,我们设计了四个主要功能:

Widget _buildQuickActions(BuildContext context) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(
        '快捷功能',
        style: TextStyle(
          fontSize: 18.sp,
          fontWeight: FontWeight.bold,
        ),
      ),
      SizedBox(height: 12.h),
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          _buildActionItem(
            icon: Icons.family_restroom,
            label: '家庭成员',
            color: Colors.blue,
            onTap: () => Get.to(() => const FamilyListScreen()),
          ),
          _buildActionItem(
            icon: Icons.alarm,
            label: '用药提醒',
            color: Colors.orange,
            onTap: () => Get.to(() => const ReminderListScreen()),
          ),
          _buildActionItem(
            icon: Icons.menu_book,
            label: '用药知识',
            color: Colors.green,
            onTap: () => Get.to(() => const KnowledgeScreen()),
          ),
          _buildActionItem(
            icon: Icons.emergency,
            label: '急救指南',
            color: Colors.red,
            onTap: () => Get.to(() => const EmergencyScreen()),
          ),
        ],
      ),
    ],
  );
}

使用Row将四个功能按钮横向排列。每个按钮都有独特的颜色和图标。

接下来是单个功能按钮的实现:

Widget _buildActionItem({
  required IconData icon,
  required String label,
  required Color color,
  required VoidCallback onTap,
}) {
  return GestureDetector(
    onTap: onTap,
    child: Column(
      children: [
        Container(
          width: 56.w,
          height: 56.w,
          decoration: BoxDecoration(
            color: color.withOpacity(0.1),
            borderRadius: BorderRadius.circular(16.r),
          ),
          child: Icon(icon, color: color, size: 28.sp),
        ),
        SizedBox(height: 8.h),
        Text(
          label,
          style: TextStyle(fontSize: 12.sp),
        ),
      ],
    ),
  );
}

每个功能按钮由一个带圆角的彩色背景容器和下方的文字标签组成。容器使用color.withOpacity(0.1)让背景色半透明。使用GetX的Get.to()方法进行页面导航。

智能提醒事项的实现

提醒事项区域是首页的核心功能之一,它能实时监控药品状态并给出提醒:

Widget _buildAlertSection(BuildContext context) {
  return Consumer<MedicineProvider>(
    builder: (context, provider, child) {
      final expiredCount = provider.expiredMedicines.length;
      final expiringSoonCount = provider.expiringSoonMedicines.length;
      final lowStockCount = provider.lowStockMedicines.length;

      if (expiredCount == 0 && expiringSoonCount == 0 && lowStockCount == 0) {
        return const SizedBox.shrink();
      }

      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            '提醒事项',
            style: TextStyle(
              fontSize: 18.sp,
              fontWeight: FontWeight.bold,
            ),
          ),
          SizedBox(height: 12.h),
          if (expiredCount > 0)
            _buildAlertCard(
              icon: Icons.warning,
              title: '已过期药品',
              subtitle: '有 $expiredCount 种药品已过期,请及时处理',
              color: Colors.red,
              onTap: () => Get.to(() => const ExpiringMedicinesScreen()),
            ),
          if (expiringSoonCount > 0)
            _buildAlertCard(
              icon: Icons.access_time,
              title: '即将过期',
              subtitle: '有 $expiringSoonCount 种药品即将在30天内过期',
              color: Colors.orange,
              onTap: () => Get.to(() => const ExpiringMedicinesScreen()),
            ),
          if (lowStockCount > 0)
            _buildAlertCard(
              icon: Icons.inventory_2,
              title: '库存不足',
              subtitle: '有 $lowStockCount 种药品库存不足,请及时补充',
              color: Colors.amber,
              onTap: () => Get.to(() => const LowStockScreen()),
            ),
        ],
      );
    },
  );
}

使用Consumer来监听MedicineProvider的状态变化。获取三种状态的药品数量:已过期、即将过期和库存不足。如果所有状态都正常,就返回SizedBox.shrink()隐藏提醒区域。

提醒卡片的实现代码如下:

Widget _buildAlertCard({
  required IconData icon,
  required String title,
  required String subtitle,
  required Color color,
  required VoidCallback onTap,
}) {
  return GestureDetector(
    onTap: onTap,
    child: Container(
      margin: EdgeInsets.only(bottom: 8.h),
      padding: EdgeInsets.all(12.w),
      decoration: BoxDecoration(
        color: color.withOpacity(0.1),
        borderRadius: BorderRadius.circular(12.r),
        border: Border.all(color: color.withOpacity(0.3)),
      ),
      child: Row(
        children: [
          Icon(icon, color: color, size: 24.sp),
          SizedBox(width: 12.w),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  title,
                  style: TextStyle(
                    fontSize: 14.sp,
                    fontWeight: FontWeight.bold,
                    color: color,
                  ),
                ),
                Text(
                  subtitle,
                  style: TextStyle(
                    fontSize: 12.sp,
                    color: Colors.grey[600],
                  ),
                ),
              ],
            ),
          ),
          Icon(Icons.chevron_right, color: color),
        ],
      ),
    ),
  );
}

每个提醒卡片都采用了对应状态的主题色。卡片内部采用Row布局,从左到右依次是状态图标、文字信息、箭头图标。

今日用药提醒的展示

今日用药区域展示当天需要服用的药品提醒:

Widget _buildTodayReminders(BuildContext context) {
  return Consumer<ReminderProvider>(
    builder: (context, provider, child) {
      final activeReminders = provider.activeReminders;

      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                '今日用药',
                style: TextStyle(
                  fontSize: 18.sp,
                  fontWeight: FontWeight.bold,
                ),
              ),
              TextButton(
                onPressed: () => Get.to(() => const TodayReminderScreen()),
                child: const Text('查看全部'),
              ),
            ],
          ),
          SizedBox(height: 8.h),
          if (activeReminders.isEmpty)
            Container(
              padding: EdgeInsets.all(20.w),
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(12.r),
              ),
              child: Center(
                child: Text(
                  '今日暂无用药提醒',
                  style: TextStyle(
                    color: Colors.grey[500],
                    fontSize: 14.sp,
                  ),
                ),
              ),
            )
          else
            ...activeReminders.take(3).map((reminder) => _buildReminderCard(reminder)),
        ],
      );
    },
  );
}

使用Consumer来监听ReminderProvider。标题栏左侧是"今日用药"标题,右侧是"查看全部"按钮。如果有提醒,使用take(3)只显示前三条。

用药提醒卡片的实现:

Widget _buildReminderCard(dynamic reminder) {
  return Container(
    margin: EdgeInsets.only(bottom: 8.h),
    padding: EdgeInsets.all(12.w),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(12.r),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withOpacity(0.05),
          blurRadius: 10,
          offset: const Offset(0, 2),
        ),
      ],
    ),
    child: Row(
      children: [
        Container(
          width: 48.w,
          height: 48.w,
          decoration: BoxDecoration(
            color: const Color(0xFF00897B).withOpacity(0.1),
            borderRadius: BorderRadius.circular(12.r),
          ),
          child: Icon(
            Icons.medication,
            color: const Color(0xFF00897B),
            size: 24.sp,
          ),
        ),
        SizedBox(width: 12.w),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                reminder.medicineName,
                style: TextStyle(
                  fontSize: 14.sp,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Text(
                '${reminder.memberName} · ${reminder.dosage}',
                style: TextStyle(
                  fontSize: 12.sp,
                  color: Colors.grey[600],
                ),
              ),
            ],
          ),
        ),
        Text(
          reminder.frequency,
          style: TextStyle(
            fontSize: 12.sp,
            color: const Color(0xFF00897B),
          ),
        ),
      ],
    ),
  );
}

每个提醒卡片都包含药品图标、药品名称、服药人、用量和频率等信息。使用BoxShadow为卡片添加阴影效果。

家庭成员展示区域

最后是家庭成员区域,采用横向滚动的方式展示:

Widget _buildFamilySection(BuildContext context) {
  return Consumer<FamilyProvider>(
    builder: (context, provider, child) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                '家庭成员',
                style: TextStyle(
                  fontSize: 18.sp,
                  fontWeight: FontWeight.bold,
                ),
              ),
              TextButton(
                onPressed: () => Get.to(() => const FamilyListScreen()),
                child: const Text('管理'),
              ),
            ],
          ),
          SizedBox(height: 8.h),
          SizedBox(
            height: 100.h,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: provider.members.length,
              itemBuilder: (context, index) {
                final member = provider.members[index];
                return Container(
                  width: 80.w,
                  margin: EdgeInsets.only(right: 12.w),
                  child: Column(
                    children: [
                      CircleAvatar(
                        radius: 30.r,
                        backgroundColor: Colors.teal.withOpacity(0.1),
                        child: Text(
                          member.name.substring(0, 1),
                          style: TextStyle(
                            fontSize: 20.sp,
                            color: Colors.teal,
                          ),
                        ),
                      ),
                      SizedBox(height: 8.h),
                      Text(
                        member.name,
                        style: TextStyle(fontSize: 12.sp),
                        overflow: TextOverflow.ellipsis,
                      ),
                      Text(
                        member.relationship,
                        style: TextStyle(
                          fontSize: 10.sp,
                          color: Colors.grey[500],
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
        ],
      );
    },
  );
}

使用ListView.builder配合scrollDirection: Axis.horizontal实现横向滚动。每个成员显示为一个圆形头像,使用CircleAvatar组件实现。

屏幕适配

在整个首页的实现中,使用了.w.h.sp.r这样的后缀。这些都来自flutter_screenutil包,能帮助我们实现精确的屏幕适配。

状态管理与性能优化

首页使用Provider进行状态管理,当数据发生变化时,UI会自动刷新。使用Consumer精确控制Widget的重建范围。在今日用药区域使用take(3)限制显示数量,在家庭成员区域使用ListView.builder实现懒加载。

总结

通过本文的讲解,我们完整实现了家庭药箱管理应用的首页。首页通过四个功能区域,让用户快速了解药品状态和用药安排。技术上使用Provider进行状态管理,使用GetX进行页面导航,使用flutter_screenutil进行屏幕适配。


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

在这里你可以与更多开发者交流Flutter for OpenHarmony的开发经验,分享你的项目成果,获取最新的技术资讯。社区汇聚了众多热爱鸿蒙生态的开发者,大家互相帮助、共同进步。无论你是刚入门的新手,还是经验丰富的老手,都能在这里找到志同道合的伙伴。让我们一起推动鸿蒙生态的发展,创造更多优秀的跨平台应用!

药品过期预警横幅

在首页顶部添加醒目的过期预警:

Widget _buildExpiryWarningBanner(BuildContext context) {
  return Consumer<MedicineProvider>(
    builder: (context, provider, child) {
      final expiredCount = provider.expiredMedicines.length;
      final expiringSoonCount = provider.expiringSoonMedicines.length;
      
      if (expiredCount == 0 && expiringSoonCount == 0) {
        return const SizedBox.shrink();
      }
      
      return Container(
        margin: EdgeInsets.all(16.w),
        padding: EdgeInsets.all(16.w),
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: expiredCount > 0
                ? [const Color(0xFFF44336), const Color(0xFFE57373)]
                : [const Color(0xFFFF9800), const Color(0xFFFFB74D)],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
          ),
          borderRadius: BorderRadius.circular(12.r),
          boxShadow: [
            BoxShadow(
              color: (expiredCount > 0 ? const Color(0xFFF44336) : const Color(0xFFFF9800))
                  .withOpacity(0.3),
              blurRadius: 10,
              offset: const Offset(0, 4),
            ),
          ],
        ),
        child: Row(
          children: [
            Icon(
              expiredCount > 0 ? Icons.warning : Icons.access_time,
              color: Colors.white,
              size: 32.sp,
            ),
            SizedBox(width: 12.w),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    expiredCount > 0 ? '药品已过期' : '药品即将过期',
                    style: TextStyle(
                      fontSize: 16.sp,
                      fontWeight: FontWeight.bold,
                      color: Colors.white,
                    ),
                  ),
                  SizedBox(height: 4.h),
                  Text(
                    expiredCount > 0
                        ? '有 $expiredCount 种药品已过期,请及时处理'
                        : '有 $expiringSoonCount 种药品即将在30天内过期',
                    style: TextStyle(
                      fontSize: 12.sp,
                      color: Colors.white.withOpacity(0.9),
                    ),
                  ),
                ),
              ),
            ),
            Icon(Icons.chevron_right, color: Colors.white),
          ],
        ),
      );
    },
  );
}

过期预警横幅使用渐变背景和阴影效果,非常醒目。已过期的药品用红色,即将过期的用橙色。这种视觉层次让用户能够快速识别紧急程度。横幅可以点击跳转到详情页面查看具体的过期药品列表。

渐变色的使用让横幅更有层次感,白色文字在彩色背景上清晰可读。警告图标和右箭头提示用户这是一个可交互的元素。这种设计既美观又实用,能够有效提醒用户及时处理过期药品。

今日服药进度

显示今日服药任务的完成情况:

Widget _buildTodayProgress(BuildContext context) {
  return Consumer<ReminderProvider>(
    builder: (context, provider, child) {
      final todayReminders = provider.getTodayReminders();
      final completedCount = todayReminders.where((r) => r.isCompleted).length;
      final totalCount = todayReminders.length;
      final progress = totalCount > 0 ? completedCount / totalCount : 0.0;
      
      return Container(
        margin: EdgeInsets.symmetric(horizontal: 16.w),
        padding: EdgeInsets.all(20.w),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(16.r),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.05),
              blurRadius: 10,
              offset: const Offset(0, 2),
            ),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  '今日服药进度',
                  style: TextStyle(
                    fontSize: 16.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Text(
                  '$completedCount/$totalCount',
                  style: TextStyle(
                    fontSize: 14.sp,
                    color: const Color(0xFF00897B),
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ],
            ),
            SizedBox(height: 12.h),
            ClipRRect(
              borderRadius: BorderRadius.circular(10.r),
              child: LinearProgressIndicator(
                value: progress,
                minHeight: 8.h,
                backgroundColor: Colors.grey[200],
                valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF00897B)),
              ),
            ),
            SizedBox(height: 8.h),
            Text(
              totalCount == 0
                  ? '今日暂无服药任务'
                  : completedCount == totalCount
                      ? '太棒了!今日服药任务已全部完成'
                      : '还有 ${totalCount - completedCount} 次服药任务待完成',
              style: TextStyle(
                fontSize: 12.sp,
                color: Colors.grey[600],
              ),
            ),
          ],
        ),
      );
    },
  );
}

服药进度卡片显示今日服药任务的完成情况,使用进度条可视化展示。进度条使用主题色,完成度一目了然。底部的文字提示根据完成情况动态变化,全部完成时显示鼓励性文字。

这种设计让用户能够快速了解今日的服药情况,避免遗漏。进度条的视觉反馈比单纯的数字更直观,提升了用户体验。

健康数据概览

展示家庭成员的健康数据统计:

Widget _buildHealthOverview(BuildContext context) {
  return Consumer2<FamilyProvider, HealthProvider>(
    builder: (context, familyProvider, healthProvider, child) {
      final members = familyProvider.members;
      final todayRecords = healthProvider.getTodayRecords();
      
      return Container(
        margin: EdgeInsets.all(16.w),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '健康数据',
              style: TextStyle(
                fontSize: 18.sp,
                fontWeight: FontWeight.bold,
              ),
            ),
            SizedBox(height: 12.h),
            Row(
              children: [
                Expanded(
                  child: _buildHealthStatCard(
                    icon: Icons.people,
                    label: '家庭成员',
                    value: '${members.length}',
                    color: Colors.blue,
                  ),
                ),
                SizedBox(width: 12.w),
                Expanded(
                  child: _buildHealthStatCard(
                    icon: Icons.favorite,
                    label: '今日记录',
                    value: '${todayRecords.length}',
                    color: Colors.red,
                  ),
                ),
              ],
            ),
            SizedBox(height: 12.h),
            Row(
              children: [
                Expanded(
                  child: _buildHealthStatCard(
                    icon: Icons.medication,
                    label: '药品种类',
                    value: '${context.read<MedicineProvider>().medicines.length}',
                    color: Colors.green,
                  ),
                ),
                SizedBox(width: 12.w),
                Expanded(
                  child: _buildHealthStatCard(
                    icon: Icons.alarm,
                    label: '活跃提醒',
                    value: '${context.read<ReminderProvider>().activeReminders.length}',
                    color: Colors.orange,
                  ),
                ),
              ],
            ),
          ],
        ),
      );
    },
  );
}

Widget _buildHealthStatCard({
  required IconData icon,
  required String label,
  required String value,
  required Color color,
}) {
  return Container(
    padding: EdgeInsets.all(16.w),
    decoration: BoxDecoration(
      color: color.withOpacity(0.1),
      borderRadius: BorderRadius.circular(12.r),
      border: Border.all(color: color.withOpacity(0.3)),
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Icon(icon, color: color, size: 24.sp),
        SizedBox(height: 8.h),
        Text(
          value,
          style: TextStyle(
            fontSize: 24.sp,
            fontWeight: FontWeight.bold,
            color: color,
          ),
        ),
        Text(
          label,
          style: TextStyle(
            fontSize: 12.sp,
            color: Colors.grey[600],
          ),
        ),
      ],
    ),
  );
}

健康数据概览使用四个统计卡片展示关键指标:家庭成员数、今日健康记录数、药品种类数和活跃提醒数。每个卡片使用不同颜色,视觉上易于区分。

卡片采用浅色背景和边框,与图标颜色相呼应。数字使用大号字体突出显示,让用户一眼就能看到关键数据。这种仪表盘式的设计让首页信息更加丰富和实用。

快速操作浮动按钮

添加浮动操作按钮提供快捷功能:

Widget _buildFloatingActionButton(BuildContext context) {
  return FloatingActionButton(
    onPressed: () => _showQuickActions(context),
    backgroundColor: const Color(0xFF00897B),
    child: const Icon(Icons.add),
  );
}

void _showQuickActions(BuildContext context) {
  showModalBottomSheet(
    context: context,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(20.r)),
    ),
    builder: (sheetContext) => SafeArea(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(height: 8.h),
          Container(
            width: 40.w,
            height: 4.h,
            decoration: BoxDecoration(
              color: Colors.grey[300],
              borderRadius: BorderRadius.circular(2.r),
            ),
          ),
          SizedBox(height: 16.h),
          ListTile(
            leading: Container(
              padding: EdgeInsets.all(8.w),
              decoration: BoxDecoration(
                color: Colors.blue.withOpacity(0.1),
                shape: BoxShape.circle,
              ),
              child: const Icon(Icons.medication, color: Colors.blue),
            ),
            title: const Text('添加药品'),
            onTap: () {
              Navigator.pop(sheetContext);
              Get.to(() => const AddMedicineScreen());
            },
          ),
          ListTile(
            leading: Container(
              padding: EdgeInsets.all(8.w),
              decoration: BoxDecoration(
                color: Colors.orange.withOpacity(0.1),
                shape: BoxShape.circle,
              ),
              child: const Icon(Icons.alarm, color: Colors.orange),
            ),
            title: const Text('添加提醒'),
            onTap: () {
              Navigator.pop(sheetContext);
              Get.to(() => const AddReminderScreen());
            },
          ),
          ListTile(
            leading: Container(
              padding: EdgeInsets.all(8.w),
              decoration: BoxDecoration(
                color: Colors.green.withOpacity(0.1),
                shape: BoxShape.circle,
              ),
              child: const Icon(Icons.favorite, color: Colors.green),
            ),
            title: const Text('记录健康数据'),
            onTap: () {
              Navigator.pop(sheetContext);
              Get.to(() => const AddHealthRecordScreen());
            },
          ),
          ListTile(
            leading: Container(
              padding: EdgeInsets.all(8.w),
              decoration: BoxDecoration(
                color: Colors.purple.withOpacity(0.1),
                shape: BoxShape.circle,
              ),
              child: const Icon(Icons.person_add, color: Colors.purple),
            ),
            title: const Text('添加家庭成员'),
            onTap: () {
              Navigator.pop(sheetContext);
              Get.to(() => const AddFamilyMemberScreen());
            },
          ),
          SizedBox(height: 16.h),
        ],
      ),
    ),
  );
}

浮动操作按钮固定在屏幕右下角,点击后弹出快速操作菜单。菜单包含四个常用功能:添加药品、添加提醒、记录健康数据、添加家庭成员。每个选项都有彩色图标,视觉上易于识别。

底部菜单使用圆角设计,顶部有一个小横条作为拖动提示。这种设计符合现代移动应用的交互习惯,用户体验流畅自然。

最近活动时间线

显示家庭成员的最近活动:

Widget _buildRecentActivities(BuildContext context) {
  return Container(
    margin: EdgeInsets.all(16.w),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              '最近活动',
              style: TextStyle(
                fontSize: 18.sp,
                fontWeight: FontWeight.bold,
              ),
            ),
            TextButton(
              onPressed: () => Get.to(() => const ActivityLogScreen()),
              child: const Text('查看全部'),
            ),
          ],
        ),
        SizedBox(height: 12.h),
        _buildActivityItem(
          icon: Icons.medication,
          title: '张三服用了阿莫西林',
          time: '10分钟前',
          color: const Color(0xFF00897B),
        ),
        _buildActivityItem(
          icon: Icons.favorite,
          title: '李四记录了血压数据',
          time: '1小时前',
          color: Colors.red,
        ),
        _buildActivityItem(
          icon: Icons.add_box,
          title: '添加了新药品:感冒灵',
          time: '2小时前',
          color: Colors.blue,
        ),
      ],
    ),
  );
}

Widget _buildActivityItem({
  required IconData icon,
  required String title,
  required String time,
  required Color color,
}) {
  return Container(
    margin: EdgeInsets.only(bottom: 12.h),
    padding: EdgeInsets.all(12.w),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(12.r),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withOpacity(0.05),
          blurRadius: 10,
          offset: const Offset(0, 2),
        ),
      ],
    ),
    child: Row(
      children: [
        Container(
          padding: EdgeInsets.all(8.w),
          decoration: BoxDecoration(
            color: color.withOpacity(0.1),
            shape: BoxShape.circle,
          ),
          child: Icon(icon, color: color, size: 20.sp),
        ),
        SizedBox(width: 12.w),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                title,
                style: TextStyle(
                  fontSize: 14.sp,
                  fontWeight: FontWeight.w500,
                ),
              ),
              Text(
                time,
                style: TextStyle(
                  fontSize: 12.sp,
                  color: Colors.grey[600],
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

活动时间线展示家庭成员的最近操作记录,包括服药、健康记录、药品管理等。每条活动显示图标、描述和时间,让用户了解家庭的健康管理动态。

不同类型的活动使用不同颜色的图标,视觉上易于区分。时间使用相对格式显示,更符合用户的阅读习惯。这种设计让首页更有活力,用户能够感受到应用的实时性。

健康小贴士

每日推送健康知识:

Widget _buildHealthTip(BuildContext context) {
  final tips = [
    '每天至少喝8杯水,保持身体水分充足',
    '药品应存放在阴凉干燥处,避免阳光直射',
    '服药前请仔细阅读说明书,了解用法用量',
    '定期检查药品有效期,及时清理过期药品',
    '不同药品之间可能存在相互作用,请咨询医生',
  ];
  
  final random = Random();
  final tip = tips[random.nextInt(tips.length)];
  
  return Container(
    margin: EdgeInsets.all(16.w),
    padding: EdgeInsets.all(16.w),
    decoration: BoxDecoration(
      gradient: const LinearGradient(
        colors: [Color(0xFF4CAF50), Color(0xFF81C784)],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      ),
      borderRadius: BorderRadius.circular(12.r),
    ),
    child: Row(
      children: [
        Icon(Icons.lightbulb, color: Colors.white, size: 32.sp),
        SizedBox(width: 12.w),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                '健康小贴士',
                style: TextStyle(
                  fontSize: 14.sp,
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
              SizedBox(height: 4.h),
              Text(
                tip,
                style: TextStyle(
                  fontSize: 12.sp,
                  color: Colors.white.withOpacity(0.9),
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

健康小贴士卡片每次打开应用时随机显示一条健康知识。使用绿色渐变背景,给人清新健康的感觉。灯泡图标象征知识和启发。

这种设计不仅美化了首页,还能向用户传递有用的健康知识,提升应用的价值。随机显示的机制让用户每次打开应用都有新鲜感。

天气与健康建议

根据天气情况提供健康建议:

Widget _buildWeatherHealth(BuildContext context) {
  return Container(
    margin: EdgeInsets.all(16.w),
    padding: EdgeInsets.all(16.w),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(12.r),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withOpacity(0.05),
          blurRadius: 10,
          offset: const Offset(0, 2),
        ),
      ],
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Icon(Icons.wb_sunny, color: Colors.orange, size: 32.sp),
            SizedBox(width: 12.w),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '今日天气',
                  style: TextStyle(
                    fontSize: 14.sp,
                    color: Colors.grey[600],
                  ),
                ),
                Text(
                  '晴 25°C',
                  style: TextStyle(
                    fontSize: 20.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ],
        ),
        SizedBox(height: 12.h),
        Container(
          padding: EdgeInsets.all(12.w),
          decoration: BoxDecoration(
            color: Colors.blue.withOpacity(0.1),
            borderRadius: BorderRadius.circular(8.r),
          ),
          child: Row(
            children: [
              Icon(Icons.info_outline, color: Colors.blue, size: 20.sp),
              SizedBox(width: 8.w),
              Expanded(
                child: Text(
                  '天气晴朗,适合户外活动。注意防晒,多喝水。',
                  style: TextStyle(
                    fontSize: 12.sp,
                    color: Colors.blue[700],
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

天气健康卡片显示当前天气情况,并根据天气提供相应的健康建议。晴天提醒防晒,雨天提醒带伞,高温提醒防暑等。这种贴心的设计让应用更加智能和实用。

总结

通过本文的详细讲解,我们完整实现了家庭药箱管理应用的首页。首页不仅包含基础的功能入口,还集成了过期预警、服药进度、健康数据统计、活动时间线、健康小贴士等丰富功能。

每个功能模块都经过精心设计,使用渐变色、阴影、圆角等视觉元素提升美观度。通过Provider进行状态管理,确保数据实时更新。GetX路由让页面跳转流畅自然。flutter_screenutil保证了在不同设备上的适配效果。

整个首页的设计既美观又实用,信息层次清晰,交互流畅,为用户提供了优秀的使用体验。这样的首页设计不仅适用于药箱管理应用,也可以作为其他健康管理类应用的参考。


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

Logo

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

更多推荐