Flutter for OpenHarmony 视力保护提醒App实战 - 月统计数据分析
视力保护应用月统计功能摘要 本文介绍了视力保护提醒应用中的月统计数据分析功能实现。该功能包含三个核心组件:月度概览卡片展示总提醒次数、休息时间和评分;日历视图使用table_calendar库显示日期并支持选择;周趋势分析图表展示用眼习惯变化。 技术实现采用Flutter框架,依赖flutter_screenutil适配屏幕,get管理状态。页面布局采用Scaffold+SingleChildSc
概述
在视力保护提醒应用中,月统计数据分析是一个重要的功能模块。它帮助用户了解整个月份的用眼习惯和提醒执行情况。本文将详细讲解如何实现一个完整的月统计数据分析页面,包括月度概览、日历视图、周趋势分析等功能。
月统计数据分析的核心功能
月统计数据分析页面主要包含以下几个部分:
- 月度概览卡片 - 展示本月的总提醒次数、总休息时间和平均评分
- 日历视图 - 使用table_calendar库展示整个月的日期,支持日期选择
- 周趋势分析 - 展示每周的提醒次数和趋势变化
这些功能结合在一起,为用户提供了一个全面的月度数据视图。
项目依赖配置
在pubspec.yaml中,我们已经配置了所需的依赖:
dependencies:
flutter:
sdk: flutter
flutter_screenutil: ^5.9.0
table_calendar: ^3.0.9
get: ^4.6.5
flutter_screenutil用于屏幕适配,table_calendar用于日历显示,get用于状态管理。这些依赖都是为了支持鸿蒙系统的Flutter开发。
月统计详情页面实现
导入和类定义
class MonthlyStatsDetail extends StatefulWidget {
const MonthlyStatsDetail({super.key});
State<MonthlyStatsDetail> createState() => _MonthlyStatsDetailState();
}
定义了MonthlyStatsDetail有状态组件,用于实现月统计数据分析功能。使用StatefulWidget是因为我们需要管理日期选择的状态。createState方法返回_MonthlyStatsDetailState实例,负责管理月统计的具体逻辑。这种设计模式使月统计页面能够响应用户交互并更新显示。
状态变量初始化
class _MonthlyStatsDetailState extends State<MonthlyStatsDetail> {
late DateTime _focusedDay;
late DateTime _selectedDay;
void initState() {
super.initState();
_focusedDay = DateTime.now();
_selectedDay = DateTime.now();
}
定义了两个DateTime变量来管理日期状态。_focusedDay表示日历当前显示的月份,_selectedDay表示用户选中的日期。在initState中,我们将它们都初始化为当前日期。这样用户打开页面时,日历会显示当前月份,并且当前日期被选中。这种初始化方式提供了良好的用户体验。
主构建方法
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('月详统计'),
backgroundColor: const Color(0xFF2196F3),
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: [
_buildMonthlyOverview(),
SizedBox(height: 16.h),
_buildCalendar(),
SizedBox(height: 16.h),
_buildMonthlyTrend(),
SizedBox(height: 20.h),
],
),
),
);
}
build方法构建了整个月统计页面的布局。Scaffold提供了Material Design的基本框架。AppBar显示页面标题"月详统计",使用蓝色背景和白色文字。SingleChildScrollView包装了主体内容,确保当内容超过屏幕高度时可以滚动。通过SizedBox添加垂直间距,使页面布局更加清晰。这种分层的UI结构使代码易于理解和维护。
月度概览卡片实现
概览容器
Widget _buildMonthlyOverview() {
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.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'本月概览',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildOverviewItem('总提醒', '224次', const Color(0xFF2196F3)),
_buildOverviewItem('总休息', '1120分', const Color(0xFF4CAF50)),
_buildOverviewItem('平均评分', '8.1', const Color(0xFFFFC107)),
],
),
],
),
);
}
_buildMonthlyOverview方法构建月度概览区域。使用Container创建一个白色卡片,添加圆角和阴影效果。Column竖直排列标题和数据行。标题使用较大的加粗字体。Row使用mainAxisAlignment: MainAxisAlignment.spaceAround均匀分布三个数据项。这种设计使月度概览数据清晰易读,用户可以快速了解一月的关键指标。
概览项目组件
Widget _buildOverviewItem(String label, String value, Color color) {
return Column(
children: [
Text(
value,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: color,
),
),
SizedBox(height: 4.h),
Text(
label,
style: TextStyle(fontSize: 12.sp, color: Colors.grey),
),
],
);
}
_buildOverviewItem是一个辅助方法,用于构建单个概览项。使用Column竖直排列数值和标签。数值使用较大的加粗字体和指定的颜色,提高了重要数据的可见性。标签使用较小的灰色字体,作为数值的说明。这种设计模式提高了代码的复用性,避免了重复的UI构建代码。
日历视图实现
日历容器
Widget _buildCalendar() {
return Container(
margin: EdgeInsets.symmetric(horizontal: 16.w),
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: TableCalendar(
firstDay: DateTime.utc(2024, 1, 1),
lastDay: DateTime.utc(2025, 12, 31),
focusedDay: _focusedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
},
calendarStyle: CalendarStyle(
selectedDecoration: BoxDecoration(
color: const Color(0xFF2196F3),
shape: BoxShape.circle,
),
todayDecoration: BoxDecoration(
color: const Color(0xFF2196F3).withOpacity(0.3),
shape: BoxShape.circle,
),
),
headerStyle: HeaderStyle(
formatButtonVisible: false,
titleCentered: true,
titleTextStyle: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
),
);
}
_buildCalendar方法构建日历视图区域。使用Container创建一个白色卡片。TableCalendar是table_calendar库提供的核心组件。firstDay和lastDay定义了日历的可选范围。focusedDay表示当前显示的月份。selectedDayPredicate用于判断某个日期是否被选中。onDaySelected回调在用户选择日期时触发,通过setState更新_selectedDay和_focusedDay。calendarStyle定义了日历的样式,包括选中日期的颜色和今天的颜色。这种设计使用户能够直观地选择和查看日期。
周趋势分析实现
趋势容器
Widget _buildMonthlyTrend() {
return Container(
margin: EdgeInsets.symmetric(horizontal: 16.w),
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'月度趋势',
style: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 12.h),
...[
{'week': '第1周', 'reminders': 52, 'color': const Color(0xFF2196F3)},
{'week': '第2周', 'reminders': 56, 'color': const Color(0xFF4CAF50)},
{'week': '第3周', 'reminders': 58, 'color': const Color(0xFFFFC107)},
{'week': '第4周', 'reminders': 58, 'color': const Color(0xFF00BCD4)},
].map((item) => _buildWeekItem(
item['week'] as String,
item['reminders'] as int,
item['color'] as Color,
)),
],
),
);
}
_buildMonthlyTrend方法构建月度趋势区域。使用Container创建一个白色卡片。标题使用较大的加粗字体。使用spread operator (…)展开列表中的Widget。定义了一个包含四周数据的列表,每周包含周标签、提醒次数和颜色。使用map方法将每个数据项转换为_buildWeekItem Widget。这种设计使月度趋势数据清晰地展示在卡片中。
周项目组件
Widget _buildWeekItem(String week, int reminders, Color color) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
children: [
SizedBox(
width: 50.w,
child: Text(
week,
style: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.w500),
),
),
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(4.r),
child: LinearProgressIndicator(
value: reminders / 60,
minHeight: 8.h,
backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(color),
),
),
),
SizedBox(width: 12.w),
Text(
'$reminders次',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.bold,
color: color,
),
),
],
),
);
}
}
_buildWeekItem方法构建单个周的趋势项。使用Row横向排列周标签、进度条和提醒次数。第一个SizedBox固定周标签的宽度为50.w。Expanded使进度条占据中间的剩余空间。LinearProgressIndicator用于可视化显示提醒次数的比例,value: reminders / 60将提醒次数转换为0-1之间的比例值。ClipRRect为进度条添加圆角。最后显示具体的提醒次数。这种设计使用户能够快速比较不同周的提醒次数。
屏幕适配处理
在整个页面中,我们使用flutter_screenutil库来处理屏幕适配。.w表示宽度单位,.h表示高度单位,.sp表示字体大小单位。这样可以确保在不同屏幕尺寸的设备上,UI元素的大小和间距都能正确显示。例如,EdgeInsets.all(16.w)表示四周都有16个宽度单位的边距。TextStyle(fontSize: 16.sp)表示字体大小为16个字体单位。
日历库的使用
table_calendar库提供了强大的日历功能,包括日期选择、月份导航、事件标记等。在这个例子中,我们使用了TableCalendar来显示整个月的日期。通过配置CalendarStyle和HeaderStyle,我们可以自定义日历的样式。
数据绑定与更新
在实际应用中,月统计数据应该从数据库或API获取。可以在initState中加载数据,然后通过setState更新UI。例如:
void initState() {
super.initState();
_focusedDay = DateTime.now();
_selectedDay = DateTime.now();
_loadMonthlyData();
}
void _loadMonthlyData() {
// 从数据库或API加载月度数据
// 然后调用setState更新UI
}
总结
月统计数据分析页面通过组合多个UI组件,为用户提供了一个全面的月度数据视图。使用table_calendar库简化了日历的实现,使用LinearProgressIndicator可视化显示了趋势数据。通过flutter_screenutil库,我们确保了UI在不同屏幕尺寸上的正确显示。
这个页面的设计遵循了Material Design的设计规范,使用了统一的颜色方案和间距。用户可以通过选择日期来查看特定日期的详细数据,通过周趋势分析来了解整个月的变化趋势。
在实际应用中,我们可以进一步扩展这个系统,添加更多的筛选选项、数据导出等功能。例如,可以添加月份选择器让用户查看不同月份的数据,可以添加数据导出功能让用户保存数据。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)