Flutter for OpenHarmony 视力保护提醒App实战 - 提醒时间设置与管理
本文介绍了提醒时间设置与管理功能的实现方案,主要包括三个核心部分:1) 提醒设置页面的整体设计,采用Flutter框架构建有状态Widget管理用户设置;2) 提醒时间选择功能,通过网格布局展示多个可选时间点,用户可点击切换状态;3) 通知类型配置,支持声音、振动和弹窗三种提醒方式。系统采用响应式设计,使用GetX框架进行状态管理,通过容器装饰和阴影效果提升UI体验。该方案实现了灵活可配置的提醒功

提醒时间设置与管理是应用的重要功能,它允许用户自定义提醒的时间和方式。本文将详细讲解如何实现一个完整的提醒时间设置系统,包括时间选择、通知类型配置、规则引擎和执行管理。
提醒设置页面的整体设计
提醒设置页面包含提醒时间选择、通知类型配置和高级设置等多个部分。这样的设计可以让用户灵活地配置提醒功能。
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../../controllers/app_controller.dart';
class ReminderSettingsDetail extends StatefulWidget {
const ReminderSettingsDetail({super.key});
State<ReminderSettingsDetail> createState() => _ReminderSettingsDetailState();
}
class _ReminderSettingsDetailState extends State<ReminderSettingsDetail> {
final AppController appController = Get.find<AppController>();
late List<bool> _reminderTimes;
void initState() {
super.initState();
_reminderTimes = [true, true, true, true, true, false, false, false];
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('提醒设置'),
backgroundColor: const Color(0xFF2196F3),
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: [
_buildReminderTimesSection(),
SizedBox(height: 16.h),
_buildNotificationTypeSection(),
SizedBox(height: 16.h),
_buildAdvancedSettings(),
SizedBox(height: 20.h),
],
),
),
);
}
这段代码定义了提醒设置页面的基本结构。导入了Flutter的Material库、屏幕适配库和GetX框架。ReminderSettingsDetail是一个有状态Widget,用于管理提醒设置页面的状态。通过Get.find()获取应用控制器实例,用于管理全局状态。_reminderTimes列表用于跟踪每个提醒时间的启用状态,初始化时前五个时间段启用,后三个禁用。build方法返回一个Scaffold,其中body使用SingleChildScrollView包装一个Column,Column包含三个主要组件:时间选择、通知类型、高级设置。
提醒设置页面使用有状态Widget来管理提醒时间的启用状态。
提醒时间选择的实现
提醒时间选择部分允许用户选择一天中的多个提醒时间。这是一个网格布局,每个时间显示为一个可点击的按钮。
Widget _buildReminderTimesSection() {
final times = ['09:00', '12:00', '15:00', '18:00', '21:00', '06:00', '10:00', '14:00'];
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: 12.h),
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 8.w,
mainAxisSpacing: 8.h,
),
itemCount: times.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () => setState(() => _reminderTimes[index] = !_reminderTimes[index]),
child: Container(
decoration: BoxDecoration(
color: _reminderTimes[index] ? const Color(0xFF2196F3) : Colors.grey[200],
borderRadius: BorderRadius.circular(8.r),
),
child: Center(
child: Text(
times[index],
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.bold,
color: _reminderTimes[index] ? Colors.white : Colors.black,
),
),
),
),
);
},
),
],
),
);
}
_buildReminderTimesSection方法创建了提醒时间选择区域。定义了times列表包含八个提醒时间。Container创建白色卡片容器,margin设置外边距,padding设置内边距。BoxDecoration定义卡片的样式,包括白色背景、圆角和阴影效果。Column作为主要布局容器,包含标题和网格。GridView.builder实现4列的网格布局,shrinkWrap: true使网格自适应高度,physics: const NeverScrollableScrollPhysics()禁用网格滚动。GestureDetector捕获点击事件,使用setState切换提醒时间的启用状态。Container创建时间按钮,选中状态使用蓝色背景,未选中状态使用灰色背景。
时间选择使用网格布局展示所有提醒时间,用户可以快速选择或取消多个提醒时间。
通知类型配置的实现
通知类型配置部分允许用户选择提醒的通知方式。应用支持三种通知方式:声音提醒、振动提醒和弹窗提醒。
Widget _buildNotificationTypeSection() {
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: 16.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 12.h),
_buildNotificationOption('声音提醒', Icons.volume_up, true),
_buildNotificationOption('振动提醒', Icons.vibration, true),
_buildNotificationOption('弹窗提醒', Icons.notifications, true),
],
),
);
}
Widget _buildNotificationOption(String title, IconData icon, bool enabled) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
children: [
Icon(icon, color: const Color(0xFF2196F3), size: 20.sp),
SizedBox(width: 12.w),
Expanded(
child: Text(
title,
style: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w500),
),
),
Switch(
value: enabled,
onChanged: (value) {},
activeColor: const Color(0xFF2196F3),
),
],
),
);
}
_buildNotificationTypeSection方法创建了通知类型配置区域。Container创建白色卡片容器,margin设置外边距,padding设置内边距。Column作为主要布局容器,包含标题和三个通知选项。_buildNotificationOption辅助方法负责构建每个通知选项。Row用于水平排列图标、标题和开关。Icon显示通知类型的图标,color: const Color(0xFF2196F3)使用蓝色。Expanded使标题占据剩余空间。Switch组件让用户能够快速启用或禁用各种通知方式,activeColor: const Color(0xFF2196F3)使激活状态为蓝色。
通知类型配置使用Switch组件提供了直观的开关方式。
高级设置的实现
高级设置部分允许用户配置更多的提醒选项。包括工作时间内提醒、休息时间内提醒和夜间勿扰等选项。
Widget _buildAdvancedSettings() {
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),
),
],
),
Widget _buildSettingItem(String title, bool enabled) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
children: [
Expanded(
child: Text(
title,
style: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w500),
),
),
Switch(
value: enabled,
onChanged: (value) {},
activeColor: const Color(0xFF2196F3),
),
],
),
);
}
_buildAdvancedSettings方法创建了高级设置区域。Container创建白色卡片容器,margin设置外边距,padding设置内边距。Column作为主要布局容器,包含标题和三个设置项。_buildSettingItem辅助方法负责构建每个设置项。Row用于水平排列标题和开关。Expanded使标题占据剩余空间。Switch组件让用户能够快速启用或禁用各种高级选项。这些高级选项允许用户根据不同的场景和时间段精细控制提醒行为。
高级设置提供了更多的定制选项,让用户能够根据自己的需求调整提醒行为。
提醒规则引擎
提醒规则引擎用于管理和执行复杂的提醒规则,支持多种条件组合。
enum RuleCondition {
timeRange('时间范围'),
dayOfWeek('星期几'),
workingHours('工作时间'),
breakTime('休息时间'),
screenTime('用眼时间');
final String displayName;
const RuleCondition(this.displayName);
}
class ReminderRule {
final String id;
final String name;
final List<int> reminderTimes;
final List<RuleCondition> conditions;
final bool enabled;
final DateTime createdAt;
final int priority;
ReminderRule({
required this.id,
required this.name,
required this.reminderTimes,
required this.conditions,
required this.enabled,
required this.createdAt,
required this.priority,
});
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'reminderTimes': reminderTimes,
'conditions': conditions.map((c) => c.name).toList(),
'enabled': enabled,
'createdAt': createdAt.toIso8601String(),
'priority': priority,
};
RuleCondition枚举定义了五种规则条件类型,包括时间范围、星期几、工作时间、休息时间和用眼时间。ReminderRule类表示一条提醒规则,包含id、name、reminderTimes、conditions、enabled、createdAt和priority。toJson()方法将对象转换为Map,便于序列化和存储。这种设计提供了灵活的规则定义方式。
规则数据模型支持复杂的条件组合和优先级管理。
factory ReminderRule.fromJson(Map<String, dynamic> json) => ReminderRule(
id: json['id'],
name: json['name'],
reminderTimes: List<int>.from(json['reminderTimes']),
conditions: (json['conditions'] as List).map((c) => RuleCondition.values.byName(c)).toList(),
enabled: json['enabled'],
createdAt: DateTime.parse(json['createdAt']),
priority: json['priority'],
);
}
fromJson()工厂构造函数从Map创建对象,便于反序列化。通过List.from()将JSON数组转换为整数列表。使用RuleCondition.values.byName()将字符串转换为枚举值。DateTime.parse()将ISO8601格式的字符串转换为DateTime对象。这种工厂模式使得从JSON数据创建对象变得简单而优雅。
工厂构造函数提供了便捷的反序列化方式。
规则引擎实现
class ReminderRuleEngine {
static final ReminderRuleEngine _instance = ReminderRuleEngine._internal();
final List<ReminderRule> _rules = [];
factory ReminderRuleEngine() => _instance;
ReminderRuleEngine._internal();
void addRule(ReminderRule rule) => _rules.add(rule);
void removeRule(String ruleId) => _rules.removeWhere((rule) => rule.id == ruleId);
void updateRule(ReminderRule updatedRule) {
final index = _rules.indexWhere((rule) => rule.id == updatedRule.id);
if (index != -1) _rules[index] = updatedRule;
}
List<ReminderRule> getActiveRules() {
return _rules.where((rule) => rule.enabled).toList()..sort((a, b) => b.priority.compareTo(a.priority));
}
List<int> getRemindersForCurrentTime() {
final now = DateTime.now();
final activeRules = getActiveRules();
final reminders = <int>{};
for (var rule in activeRules) {
if (_matchesConditions(rule.conditions, now)) {
reminders.addAll(rule.reminderTimes);
}
}
return reminders.toList();
}
ReminderRuleEngine类采用单例模式管理所有的提醒规则。_rules列表存储所有的规则。addRule()、removeRule()和updateRule()方法用于管理规则。getActiveRules()方法返回所有启用的规则,按优先级排序。getRemindersForCurrentTime()方法根据当前时间和条件匹配,返回应该触发的提醒时间列表。使用Set来存储提醒时间,避免重复。
规则引擎采用了单例模式确保全局只有一个实例。
bool _matchesConditions(List<RuleCondition> conditions, DateTime dateTime) {
for (var condition in conditions) {
switch (condition) {
case RuleCondition.timeRange:
if (!_isInTimeRange(dateTime)) return false;
case RuleCondition.dayOfWeek:
if (!_isWorkingDay(dateTime)) return false;
case RuleCondition.workingHours:
if (!_isWorkingHours(dateTime)) return false;
case RuleCondition.breakTime:
if (!_isBreakTime(dateTime)) return false;
case RuleCondition.screenTime:
if (!_isScreenTimeExceeded()) return false;
}
}
return true;
}
bool _isInTimeRange(DateTime dateTime) => dateTime.hour >= 6 && dateTime.hour <= 23;
bool _isWorkingDay(DateTime dateTime) => dateTime.weekday >= 1 && dateTime.weekday <= 5;
bool _isWorkingHours(DateTime dateTime) {
final hour = dateTime.hour;
return (hour >= 9 && hour < 12) || (hour >= 14 && hour < 18);
}
bool _isBreakTime(DateTime dateTime) {
final hour = dateTime.hour;
return (hour >= 12 && hour < 14) || (hour >= 18 && hour < 20);
}
bool _isScreenTimeExceeded() => true;
}
_matchesConditions()方法检查规则条件是否匹配。使用switch语句实现了不同条件的检查。多个私有方法实现了具体的时间范围检查逻辑。_isInTimeRange()检查是否在有效时间范围内。_isWorkingDay()检查是否是工作日。_isWorkingHours()检查是否在工作时间。_isBreakTime()检查是否在休息时间。_isScreenTimeExceeded()检查用眼时间是否超过限制。这种设计提供了灵活的规则匹配功能。
条件检查采用了策略模式,通过switch语句实现了不同条件的处理。
提醒执行管理
class ReminderExecutor {
static final ReminderExecutor _instance = ReminderExecutor._internal();
final ReminderRuleEngine _ruleEngine = ReminderRuleEngine();
late Timer _executionTimer;
factory ReminderExecutor() => _instance;
ReminderExecutor._internal();
void startExecution() {
_executionTimer = Timer.periodic(const Duration(minutes: 1), (_) {
_checkAndExecuteReminders();
});
}
void stopExecution() => _executionTimer.cancel();
void _checkAndExecuteReminders() {
final reminders = _ruleEngine.getRemindersForCurrentTime();
final now = DateTime.now();
for (var reminderTime in reminders) {
if (_shouldTrigger(reminderTime, now)) {
_executeReminder(reminderTime);
}
}
}
ReminderExecutor类负责提醒的执行。采用单例模式确保只有一个执行器实例。startExecution()方法启动定时检查,每分钟检查一次是否需要触发提醒。stopExecution()方法停止定时检查。_checkAndExecuteReminders()方法获取当前应该触发的提醒列表,并逐一执行。_shouldTrigger()方法检查当前时间是否匹配提醒时间,通过整数除法和模运算解析提醒时间。_executeReminder()方法执行具体的提醒操作。这种设计支持后台自动执行提醒。
执行器使用定时器模式实现每分钟的定时检查。
提醒统计分析
class ReminderExecution {
final String id;
final int reminderTime;
final DateTime executedAt;
final bool userResponded;
final int responseTime;
ReminderExecution({
required this.id,
required this.reminderTime,
required this.executedAt,
required this.userResponded,
required this.responseTime,
});
Map<String, dynamic> toJson() => {
'id': id,
'reminderTime': reminderTime,
'executedAt': executedAt.toIso8601String(),
'userResponded': userResponded,
'responseTime': responseTime,
};
factory ReminderExecution.fromJson(Map<String, dynamic> json) => ReminderExecution(
id: json['id'],
reminderTime: json['reminderTime'],
executedAt: DateTime.parse(json['executedAt']),
userResponded: json['userResponded'],
responseTime: json['responseTime'],
);
}
ReminderExecution类表示单次提醒的执行记录。包含id、reminderTime、executedAt、userResponded和responseTime。toJson()方法将对象转换为Map,便于序列化和存储。fromJson()工厂构造函数从Map创建对象,便于反序列化。这种设计支持灵活的数据存储和检索。
执行记录数据模型包含了提醒执行的所有关键信息。
class ReminderStatistics {
static final ReminderStatistics _instance = ReminderStatistics._internal();
final List<ReminderExecution> _executions = [];
factory ReminderStatistics() => _instance;
ReminderStatistics._internal();
void recordExecution(ReminderExecution execution) => _executions.add(execution);
int getTotalReminders() => _executions.length;
int getRespondedReminders() => _executions.where((e) => e.userResponded).length;
double getResponseRate() {
if (_executions.isEmpty) return 0;
return (getRespondedReminders() / getTotalReminders()) * 100;
}
int getAverageResponseTime() {
final responded = _executions.where((e) => e.userResponded).toList();
if (responded.isEmpty) return 0;
final sum = responded.fold<int>(0, (prev, e) => prev + e.responseTime);
return sum ~/ responded.length;
}
}
ReminderStatistics类采用单例模式管理所有的提醒执行记录。recordExecution()方法记录提醒执行。getTotalReminders()方法获取总提醒次数。getRespondedReminders()方法获取用户响应的提醒次数。getResponseRate()方法计算响应率。getAverageResponseTime()方法计算平均响应时间。这种设计支持用户了解自己的提醒响应情况。
统计系统采用了数据聚合模式,提供了多个查询方法获取不同维度的统计数据。
总结
通过以上的设计,我们实现了一个完整的提醒时间设置与管理系统。包括灵活的时间选择、多种通知方式、智能规则引擎、自动执行管理和详细的统计分析。用户可以设置灵活的提醒规则、接收多种形式的提醒通知、查看提醒执行统计。这样的设计使得提醒功能更加智能和高效。
在实际应用中,我们可以进一步扩展这个系统,添加更多的规则条件、AI智能推荐、云端同步等功能。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)