请添加图片描述

前言

每天喝足够的水对健康很重要,一般建议成年人每天喝 2000ml 左右。饮水记录页面会显示今日饮水进度,让用户直观看到距离目标还差多少。

这个页面的特点是有进度条和快速选择按钮,方便用户快速记录常见的饮水量。


状态变量

饮水记录需要当前添加量、今日累计量和目标量三个数据。

class AddWaterPage extends StatefulWidget {
  const AddWaterPage({super.key});

  
  State<AddWaterPage> createState() => _AddWaterPageState();
}

class _AddWaterPageState extends State<AddWaterPage> {
  int _amount = 250;
  int _todayTotal = 1500;
  final int _goal = 2000;

_amount 是本次要添加的饮水量,默认 250ml(一杯水)。_todayTotal 是今日已记录的总量,实际项目中应该从数据库读取。_goal 是每日目标,可以在设置中修改。


进度卡片

用渐变背景的卡片展示今日饮水进度。

  Widget _buildProgressCard() {
    final progress = (_todayTotal + _amount) / _goal;
    return Container(
      padding: EdgeInsets.all(24.w),
      decoration: BoxDecoration(
        gradient: const LinearGradient(
          colors: [Color(0xFF4D96FF), Color(0xFF6BA8FF)]
        ),
        borderRadius: BorderRadius.circular(24.r),
      ),
      child: Column(
        children: [
          Icon(Icons.water_drop_rounded, size: 40.w, color: Colors.white70),
          SizedBox(height: 12.h),
          Text('今日饮水', style: TextStyle(
            fontSize: 13.sp, 
            color: Colors.white70
          )),
          SizedBox(height: 4.h),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Text('${_todayTotal + _amount}', style: TextStyle(
                fontSize: 36.sp, 
                fontWeight: FontWeight.w700, 
                color: Colors.white
              )),
              Padding(
                padding: EdgeInsets.only(bottom: 6.h), 
                child: Text(' / $_goal ml', style: TextStyle(
                  fontSize: 14.sp, 
                  color: Colors.white70
                ))
              ),
            ],
          ),

进度计算包含了本次要添加的量,这样用户可以预览添加后的效果。蓝色渐变是饮水在整个App中的主题色。


进度条

LinearProgressIndicator 显示完成进度。

          SizedBox(height: 16.h),
          ClipRRect(
            borderRadius: BorderRadius.circular(6.r),
            child: LinearProgressIndicator(
              value: progress.clamp(0.0, 1.0),
              minHeight: 8.h,
              backgroundColor: Colors.white30,
              valueColor: const AlwaysStoppedAnimation(Colors.white),
            ),
          ),
          SizedBox(height: 8.h),
          Text('${(progress * 100).toInt()}% 完成', style: TextStyle(
            fontSize: 12.sp, 
            color: Colors.white70
          )),
        ],
      ),
    );
  }

ClipRRect 给进度条加上圆角。.clamp(0.0, 1.0) 确保进度值在 0-1 之间,超过目标时显示 100%。

白色进度条在蓝色背景上很醒目,百分比文字让用户一眼看到完成情况。


饮水量选择器

用滑块选择本次添加的饮水量。

  Widget _buildAmountSelector() {
    return Container(
      padding: EdgeInsets.all(20.w),
      decoration: BoxDecoration(
        color: Colors.white, 
        borderRadius: BorderRadius.circular(20.r)
      ),
      child: Column(
        children: [
          Text('添加饮水量', style: TextStyle(
            fontSize: 14.sp, 
            color: Colors.grey[500]
          )),
          SizedBox(height: 12.h),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Text('$_amount', style: TextStyle(
                fontSize: 48.sp, 
                fontWeight: FontWeight.w700, 
                color: const Color(0xFF1A1A2E)
              )),
              Padding(
                padding: EdgeInsets.only(bottom: 8.h), 
                child: Text(' ml', style: TextStyle(
                  fontSize: 16.sp, 
                  color: Colors.grey[500]
                ))
              ),
            ],
          ),
          SizedBox(height: 20.h),
          SliderTheme(
            data: SliderTheme.of(context).copyWith(
              activeTrackColor: const Color(0xFF4D96FF), 
              inactiveTrackColor: Colors.grey[200], 
              thumbColor: const Color(0xFF4D96FF), 
              trackHeight: 6.h, 
              thumbShape: RoundSliderThumbShape(enabledThumbRadius: 12.r)
            ),
            child: Slider(
              value: _amount.toDouble(), 
              min: 50, 
              max: 1000, 
              divisions: 19, 
              onChanged: (v) => setState(() => _amount = v.toInt())
            ),
          ),
        ],
      ),
    );
  }

范围 50-1000ml,divisions: 19 把范围分成 19 份,每份约 50ml。这样滑块会吸附到 50 的倍数上。


快速选择按钮

提供常见饮水量的快捷按钮。

  Widget _buildQuickAdd() {
    final amounts = [100, 200, 250, 500];
    return Container(
      padding: EdgeInsets.all(16.w),
      decoration: BoxDecoration(
        color: Colors.white, 
        borderRadius: BorderRadius.circular(16.r)
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('快速选择', style: TextStyle(
            fontSize: 14.sp, 
            fontWeight: FontWeight.w500, 
            color: const Color(0xFF1A1A2E)
          )),
          SizedBox(height: 12.h),
          Row(
            children: amounts.map((a) => Expanded(
              child: GestureDetector(
                onTap: () => setState(() => _amount = a),
                child: Container(
                  margin: EdgeInsets.only(right: a == amounts.last ? 0 : 10.w),
                  padding: EdgeInsets.symmetric(vertical: 12.h),
                  decoration: BoxDecoration(
                    color: _amount == a ? const Color(0xFF4D96FF) : Colors.grey[100],
                    borderRadius: BorderRadius.circular(10.r),
                  ),
                  child: Center(
                    child: Text('$a ml', style: TextStyle(
                      fontSize: 13.sp, 
                      color: _amount == a ? Colors.white : Colors.grey[600], 
                      fontWeight: FontWeight.w500
                    ))
                  ),
                ),
              ),
            )).toList(),
          ),
        ],
      ),
    );
  }
}

100ml(小杯)、200ml(中杯)、250ml(标准杯)、500ml(大杯)是最常见的饮水量。点击按钮会同时更新滑块的位置。

选中的按钮用蓝色背景,和滑块颜色一致。


饮水提醒

可以结合提醒功能,定时提醒用户喝水:

// 每隔2小时提醒一次
void scheduleWaterReminder() {
  // 使用 flutter_local_notifications 插件
  // 设置重复提醒
}

这个功能可以在提醒设置页面配置。


小结

饮水记录页面的特点:

  • 显示今日饮水进度和目标
  • 进度条直观展示完成情况
  • 滑块选择饮水量
  • 快速选择按钮提高效率
  • 蓝色主题色,和App中其他饮水相关内容一致

进度展示是这个页面的亮点,让用户有明确的目标感,更有动力完成每日饮水目标。

下一篇会讲添加用药记录页面,用药记录需要输入药品名称和剂量。


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

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐