first commit
This commit is contained in:
252
lib/screens/notification_settings_screen.dart
Normal file
252
lib/screens/notification_settings_screen.dart
Normal file
@@ -0,0 +1,252 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../theme/app_theme.dart';
|
||||
import '../widgets/custom_time_picker_dialog.dart';
|
||||
|
||||
class NotificationSettingsScreen extends StatefulWidget {
|
||||
const NotificationSettingsScreen({super.key});
|
||||
|
||||
@override
|
||||
State<NotificationSettingsScreen> createState() => _NotificationSettingsScreenState();
|
||||
}
|
||||
|
||||
class _NotificationSettingsScreenState extends State<NotificationSettingsScreen> {
|
||||
bool _goalReminderEnabled = true;
|
||||
bool _dailyReportEnabled = true;
|
||||
bool _weeklyReportEnabled = false;
|
||||
TimeOfDay _goalReminderTime = const TimeOfDay(hour: 20, minute: 0);
|
||||
TimeOfDay _dailyReportTime = const TimeOfDay(hour: 22, minute: 0);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadSettings();
|
||||
}
|
||||
|
||||
Future<void> _loadSettings() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
setState(() {
|
||||
_goalReminderEnabled = prefs.getBool('goal_reminder_enabled') ?? true;
|
||||
_dailyReportEnabled = prefs.getBool('daily_report_enabled') ?? true;
|
||||
_weeklyReportEnabled = prefs.getBool('weekly_report_enabled') ?? false;
|
||||
|
||||
final goalReminderHour = prefs.getInt('goal_reminder_hour') ?? 20;
|
||||
final goalReminderMinute = prefs.getInt('goal_reminder_minute') ?? 0;
|
||||
_goalReminderTime = TimeOfDay(hour: goalReminderHour, minute: goalReminderMinute);
|
||||
|
||||
final dailyReportHour = prefs.getInt('daily_report_hour') ?? 22;
|
||||
final dailyReportMinute = prefs.getInt('daily_report_minute') ?? 0;
|
||||
_dailyReportTime = TimeOfDay(hour: dailyReportHour, minute: dailyReportMinute);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _saveSettings() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool('goal_reminder_enabled', _goalReminderEnabled);
|
||||
await prefs.setBool('daily_report_enabled', _dailyReportEnabled);
|
||||
await prefs.setBool('weekly_report_enabled', _weeklyReportEnabled);
|
||||
await prefs.setInt('goal_reminder_hour', _goalReminderTime.hour);
|
||||
await prefs.setInt('goal_reminder_minute', _goalReminderTime.minute);
|
||||
await prefs.setInt('daily_report_hour', _dailyReportTime.hour);
|
||||
await prefs.setInt('daily_report_minute', _dailyReportTime.minute);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('通知设置'),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 目标提醒
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.flag, color: AppTheme.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'目标提醒',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SwitchListTile(
|
||||
title: const Text('启用目标提醒'),
|
||||
subtitle: const Text('当接近或超过时间目标时提醒'),
|
||||
value: _goalReminderEnabled,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_goalReminderEnabled = value;
|
||||
});
|
||||
_saveSettings();
|
||||
},
|
||||
),
|
||||
if (_goalReminderEnabled) ...[
|
||||
const SizedBox(height: 8),
|
||||
ListTile(
|
||||
title: const Text('提醒时间'),
|
||||
subtitle: Text(
|
||||
'${_goalReminderTime.hour.toString().padLeft(2, '0')}:${_goalReminderTime.minute.toString().padLeft(2, '0')}',
|
||||
),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () async {
|
||||
final TimeOfDay? picked = await CustomTimePickerDialog.show(
|
||||
context: context,
|
||||
title: '选择提醒时间',
|
||||
initialTime: _goalReminderTime,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
_goalReminderTime = picked;
|
||||
});
|
||||
await _saveSettings();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// 每日报告
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.today, color: AppTheme.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'每日报告',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SwitchListTile(
|
||||
title: const Text('启用每日报告'),
|
||||
subtitle: const Text('每天发送使用时间摘要'),
|
||||
value: _dailyReportEnabled,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_dailyReportEnabled = value;
|
||||
});
|
||||
_saveSettings();
|
||||
},
|
||||
),
|
||||
if (_dailyReportEnabled) ...[
|
||||
const SizedBox(height: 8),
|
||||
ListTile(
|
||||
title: const Text('报告时间'),
|
||||
subtitle: Text(
|
||||
'${_dailyReportTime.hour.toString().padLeft(2, '0')}:${_dailyReportTime.minute.toString().padLeft(2, '0')}',
|
||||
),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () async {
|
||||
final TimeOfDay? picked = await CustomTimePickerDialog.show(
|
||||
context: context,
|
||||
title: '选择报告时间',
|
||||
initialTime: _dailyReportTime,
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
_dailyReportTime = picked;
|
||||
});
|
||||
await _saveSettings();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// 每周报告
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.calendar_view_week, color: AppTheme.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'每周报告',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SwitchListTile(
|
||||
title: const Text('启用每周报告'),
|
||||
subtitle: const Text('每周一发送周报摘要'),
|
||||
value: _weeklyReportEnabled,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_weeklyReportEnabled = value;
|
||||
});
|
||||
_saveSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// 说明
|
||||
Card(
|
||||
color: AppTheme.infoColor.withOpacity(0.1),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(Icons.info_outline, color: AppTheme.infoColor),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'通知功能需要系统通知权限。请在系统设置中授予通知权限。',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user