Flutter for OpenHarmony 看书管理记录App实战:阅读目标实现
阅读目标页面帮助用户设定和追踪阅读计划,主要功能包括: 顶部显示年度阅读目标卡片,包含进度条和完成统计 预测功能根据当前进度估算年度完成量 底部列表展示其他阅读目标(如月度目标) 右下角悬浮按钮支持添加新目标 页面采用深棕色渐变主题,通过可视化进度条和明确的数据展示激励用户坚持阅读。
阅读目标页面是帮助用户设定和追踪阅读计划的功能。很多人都有"今年要读50本书"这样的目标,但往往坚持不下来。这个页面就是要让用户随时看到自己的进度,激励他们继续阅读。
做这个功能的时候,我参考了一些健身App的目标追踪设计,它们都很擅长用进度可视化来激励用户。
依赖引入
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
import '../../app/routes/app_routes.dart';
这个页面用到了 percent_indicator 库来显示圆形进度条,这个库在鸿蒙设备上也能正常运行。
页面主体结构
class ReadingGoalPage extends StatelessWidget {
const ReadingGoalPage({super.key});
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFFDF8F3),
appBar: AppBar(
title: const Text('阅读目标'),
backgroundColor: const Color(0xFF5B4636),
foregroundColor: Colors.white,
),
页面结构比较简单,一个 AppBar 加上内容区域,底部有个悬浮按钮用来添加新目标。
页面内容布局
body: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildCurrentGoal(),
SizedBox(height: 20.h),
_buildGoalList(),
],
),
),
页面分两个部分:顶部是当前的主要目标(年度阅读目标),下面是其他目标列表。
悬浮添加按钮
floatingActionButton: FloatingActionButton(
backgroundColor: const Color(0xFF5B4636),
onPressed: () => Get.toNamed(AppRoutes.addGoal),
child: const Icon(Icons.add, color: Colors.white),
),
);
}
悬浮按钮用主题色背景,点击跳转到添加目标页面。放在右下角是 Material Design 的标准位置。
年度目标卡片
Widget _buildCurrentGoal() {
return Container(
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF5B4636), Color(0xFF8B7355)],
),
borderRadius: BorderRadius.circular(16.r),
),
年度目标是最重要的,用渐变背景突出显示。这个卡片会占据页面顶部很大的空间。
目标标题
child: Column(
children: [
Text('2024年阅读目标', style: TextStyle(
color: Colors.white70,
fontSize: 14.sp,
)),
SizedBox(height: 20.h),
标题用半透明白色,字号小一些,作为副标题存在。
进度展示区域
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
CircularPercentIndicator(
radius: 55.r,
lineWidth: 10.w,
percent: 0.15,
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('15%', style: TextStyle(
color: Colors.white,
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
Text('完成', style: TextStyle(
color: Colors.white70,
fontSize: 11.sp,
)),
],
),
progressColor: Colors.amber,
backgroundColor: Colors.white24,
circularStrokeCap: CircularStrokeCap.round,
),
左边是圆形进度条,用 CircularPercentIndicator 组件实现。进度条用琥珀色,和深棕色背景形成对比。中间显示完成百分比。
circularStrokeCap: CircularStrokeCap.round 让进度条两端是圆形的,看起来更柔和。
目标数据统计
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildGoalStat('目标', '50 本'),
SizedBox(height: 12.h),
_buildGoalStat('已完成', '8 本'),
SizedBox(height: 12.h),
_buildGoalStat('剩余', '42 本'),
],
),
],
),
右边显示具体的数字:目标数、已完成数、剩余数。这三个数据让用户对进度有清晰的认识。
统计项组件
Widget _buildGoalStat(String label, String value) {
return Row(
children: [
Text('$label: ', style: TextStyle(
color: Colors.white70,
fontSize: 14.sp,
)),
Text(value, style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: FontWeight.bold,
)),
],
);
}
每个统计项是标签加数值的组合,标签用半透明白色,数值用纯白加粗。
预测提示
SizedBox(height: 20.h),
Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
borderRadius: BorderRadius.circular(20.r),
),
child: Text(
'按当前进度,预计可完成 53 本 📚',
style: TextStyle(color: Colors.white, fontSize: 13.sp),
),
),
],
),
);
}
底部有个预测提示,根据当前的阅读速度预测年底能完成多少本。这个功能能给用户信心,让他们知道自己的进度是否正常。
用了一个书本的 emoji 增加趣味性。
其他目标列表
Widget _buildGoalList() {
final goals = [
{'title': '月度目标', 'target': '6本/月', 'current': '4本', 'percent': 0.67, 'status': '进行中'},
{'title': '每日阅读', 'target': '30分钟/天', 'current': '平均45分钟', 'percent': 1.0, 'status': '已达成'},
{'title': '笔记目标', 'target': '每本3条', 'current': '平均4条', 'percent': 1.0, 'status': '已达成'},
];
除了年度目标,还可以设置月度目标、每日阅读时长目标、笔记数量目标等。这些目标用列表形式展示。
目标列表标题
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('其他目标', style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: const Color(0xFF3D2914),
)),
SizedBox(height: 12.h),
标题用深棕色,和页面其他标题保持一致。
目标卡片渲染
...goals.map((g) => Container(
margin: EdgeInsets.only(bottom: 12.h),
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(g['title'] as String, style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15.sp,
)),
const Spacer(),
每个目标是一个白色卡片,标题在左边,状态标签在右边。
状态标签
Container(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
decoration: BoxDecoration(
color: (g['percent'] as double) >= 1.0
? Colors.green.withOpacity(0.1)
: const Color(0xFF5B4636).withOpacity(0.1),
borderRadius: BorderRadius.circular(4.r),
),
child: Text(
g['status'] as String,
style: TextStyle(
fontSize: 11.sp,
color: (g['percent'] as double) >= 1.0
? Colors.green
: const Color(0xFF5B4636),
),
),
),
],
),
状态标签根据完成情况显示不同颜色:已达成用绿色,进行中用主题色。这样用户一眼就能看出哪些目标完成了。
目标详情
SizedBox(height: 12.h),
Row(
children: [
Text('目标: ${g['target']}', style: TextStyle(
color: Colors.grey[600],
fontSize: 13.sp,
)),
SizedBox(width: 16.w),
Text('当前: ${g['current']}', style: TextStyle(
color: Colors.grey[600],
fontSize: 13.sp,
)),
],
),
显示目标值和当前值,让用户知道差距有多大。
进度条
SizedBox(height: 10.h),
ClipRRect(
borderRadius: BorderRadius.circular(4.r),
child: LinearProgressIndicator(
value: (g['percent'] as double).clamp(0.0, 1.0),
backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation(
(g['percent'] as double) >= 1.0
? Colors.green
: const Color(0xFF5B4636),
),
minHeight: 6.h,
),
),
],
),
)).toList(),
],
);
}
}
每个目标下面有个进度条,已达成的用绿色,进行中的用主题色。clamp(0.0, 1.0) 确保进度值不会超过 100%。
目标类型设计
这个页面支持多种类型的目标:
年度阅读目标:一年要读多少本书,这是最常见的目标类型。
月度目标:每个月要读多少本,比年度目标更容易追踪。
每日时长:每天要阅读多长时间,适合想养成阅读习惯的用户。
笔记目标:每本书要写多少条笔记,鼓励用户深度阅读。
进度计算逻辑
进度的计算需要根据目标类型来:
年度目标:已读书籍数 / 目标书籍数
月度目标:本月已读 / 月度目标
每日时长:本月平均每日时长 / 目标时长
笔记目标:平均每本笔记数 / 目标笔记数
小结
阅读目标页面通过可视化的进度展示,帮助用户追踪自己的阅读计划。圆形进度条直观地显示完成百分比,预测功能给用户信心。
多种目标类型满足不同用户的需求,状态标签让用户快速识别哪些目标已经完成。
下一篇会讲添加目标页面的实现,让用户可以创建自己的阅读目标。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)