在这里插入图片描述

提醒时间设置与管理是应用的重要功能,它允许用户自定义提醒的时间和方式。本文将详细讲解如何实现一个完整的提醒时间设置系统,包括时间选择、通知类型配置、规则引擎和执行管理。

提醒设置页面的整体设计

提醒设置页面包含提醒时间选择、通知类型配置和高级设置等多个部分。这样的设计可以让用户灵活地配置提醒功能。

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

Logo

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

更多推荐