Flutter for OpenHarmony 视力保护提醒App实战 - 通知设置详解
摘要 本文介绍了视力保护提醒应用中的通知设置功能实现,主要包括通知类型选择和夜间勿扰设置。页面采用Flutter框架开发,使用StatefulWidget管理多个开关状态。通知类型部分提供声音、振动和弹窗三种提醒方式的可选开关,夜间勿扰部分包含主开关和时间选择器。通过Container、BoxDecoration等组件实现卡片式UI设计,配合Switch组件提供交互功能。代码结构清晰,使用flut

概述
通知设置是视力保护提醒应用中的一个重要功能,它允许用户自定义通知的方式和时间。本文将详细讲解如何实现一个完整的通知设置页面,包括通知类型选择、夜间勿扰设置等功能。
通知设置的核心功能
通知设置页面主要包含以下几个部分:
- 通知类型 - 包括声音提醒、振动提醒、弹窗提醒
- 夜间勿扰 - 设置夜间勿扰的开始和结束时间
- 通知优先级 - 设置不同类型通知的优先级
这些功能结合在一起,为用户提供了一个完整的通知管理界面。
项目依赖配置
在pubspec.yaml中,我们已经配置了所需的依赖:
dependencies:
flutter:
sdk: flutter
flutter_screenutil: ^5.9.0
flutter_screenutil用于屏幕适配。这些依赖都是为了支持鸿蒙系统的Flutter开发。
通知设置页面实现
页面结构设计
通知设置页面采用StatefulWidget,因为我们需要管理多个开关的状态。页面分为两个主要部分:通知类型和夜间勿扰设置。
class NotificationSettingsDetail extends StatefulWidget {
const NotificationSettingsDetail({super.key});
State<NotificationSettingsDetail> createState() => _NotificationSettingsDetailState();
}
NotificationSettingsDetail是一个无状态的Widget类,用于创建通知设置页面。通过继承StatefulWidget,我们可以在页面中管理多个开关的状态。createState方法返回对应的State类实例。使用StatefulWidget可以让我们在用户改变设置时实时更新UI。这种设计模式是Flutter中处理有状态UI的标准方式。
状态管理初始化
在_NotificationSettingsDetailState中,我们定义了多个布尔变量来管理各个开关的状态。
class _NotificationSettingsDetailState extends State<NotificationSettingsDetail> {
bool _soundEnabled = true;
bool _vibrationEnabled = true;
bool _popupEnabled = true;
bool _quietHoursEnabled = false;
这些变量分别表示声音提醒、振动提醒、弹窗提醒和夜间勿扰是否启用。初始值设置为合理的默认值。_soundEnabled、_vibrationEnabled和_popupEnabled初始值为true,表示默认启用这些通知方式。_quietHoursEnabled初始值为false,表示默认不启用夜间勿扰。这种设计确保了用户首次使用应用时能够收到通知。
主构建方法
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('通知设置'),
backgroundColor: const Color(0xFF2196F3),
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: [
_buildNotificationSection(),
SizedBox(height: 16.h),
_buildQuietHoursSection(),
SizedBox(height: 20.h),
],
),
),
);
}
build方法是Widget的核心,返回整个页面的UI结构。Scaffold提供了Material Design的基本框架,包括AppBar和body。AppBar显示页面标题"通知设置",使用蓝色背景和白色文字。SingleChildScrollView包装了主体内容,确保当内容超过屏幕高度时可以滚动。Column竖直排列了通知类型部分、夜间勿扰部分和底部间距。这种分层的UI结构使代码易于理解和维护。
通知类型部分实现
通知类型容器
通知类型部分包含三个开关选项:声音提醒、振动提醒和弹窗提醒。
Widget _buildNotificationSection() {
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(
'通知类型',
_buildNotificationSection方法构建通知类型区域。使用Container创建一个卡片。BoxDecoration定义了卡片的样式,添加了圆角和阴影效果。Column竖直排列标题和多个通知选项。CrossAxisAlignment.start使内容左对齐。这种设计使通知类型选项清晰地展示在卡片中,用户可以快速了解可用的通知方式。
通知选项列表
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 12.h),
_buildNotificationOption('声音提醒', Icons.volume_up, _soundEnabled, (value) {
setState(() => _soundEnabled = value);
}),
_buildNotificationOption('振动提醒', Icons.vibration, _vibrationEnabled, (value) {
setState(() => _vibrationEnabled = value);
}),
_buildNotificationOption('弹窗提醒', Icons.notifications, _popupEnabled, (value) {
setState(() => _popupEnabled = value);
}),
],
),
);
}
标题使用较大的加粗字体。通过调用_buildNotificationOption方法,为每个通知选项创建对应的UI组件。三个通知选项分别代表声音提醒、振动提醒和弹窗提醒。每个选项都传入对应的图标、当前状态和状态改变回调。当用户改变开关状态时,通过setState更新对应的布尔变量。这种设计提供了清晰的通知选项管理。
通知选项组件
Widget _buildNotificationOption(
String title,
IconData icon,
bool enabled,
Function(bool) onChanged,
) {
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: onChanged,
activeColor: const Color(0xFF2196F3),
),
],
),
);
}
_buildNotificationOption方法构建单个通知选项。使用Row来横向排列图标、标题和开关。Icon组件显示了通知类型的图标,使用蓝色颜色。Expanded使标题占据中间的剩余空间。Switch组件用于切换通知的启用状态。value参数设置开关的当前状态,onChanged回调在用户改变开关状态时触发。activeColor设置开关启用时的颜色为蓝色。这种设计提供了清晰的通知选项显示和交互。
夜间勿扰部分实现
夜间勿扰容器
夜间勿扰部分包含一个主开关和两个时间选择器。
Widget _buildQuietHoursSection() {
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: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
_buildQuietHoursSection方法构建夜间勿扰区域。使用Container创建一个白色卡片,添加圆角和阴影效果。Column竖直排列标题行和时间选择器。Row使用mainAxisAlignment: MainAxisAlignment.spaceBetween使标题和开关分别显示在行的两端。这种设计使夜间勿扰设置清晰地展示在卡片中,用户可以快速启用或禁用该功能。
夜间勿扰开关和时间选择器
children: [
Text(
'夜间勿扰',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
Switch(
value: _quietHoursEnabled,
onChanged: (value) {
setState(() => _quietHoursEnabled = value);
},
activeColor: const Color(0xFF2196F3),
),
],
),
if (_quietHoursEnabled) ...[
SizedBox(height: 12.h),
_buildTimeSelector('开始时间', '22:00'),
SizedBox(height: 12.h),
_buildTimeSelector('结束时间', '08:00'),
],
],
),
);
}
标题使用较大的加粗字体。Switch组件用于启用或禁用夜间勿扰。当用户改变开关状态时,通过setState更新_quietHoursEnabled。使用if (_quietHoursEnabled) ...[...]条件来控制时间选择器的显示。当夜间勿扰启用时,时间选择器才会显示。这种条件渲染模式使UI更加简洁,只显示相关的选项。
时间选择器组件
Widget _buildTimeSelector(String label, String time) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.w500),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]!, width: 1),
borderRadius: BorderRadius.circular(8.r),
),
child: Text(
time,
style: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.w500),
),
),
],
_buildTimeSelector方法构建单个时间选择器。使用Row来横向排列标签和时间显示。标签使用较小的加粗字体。时间显示使用Container包裹,添加了边框和圆角。Border.all创建了一个灰色边框,borderRadius添加了圆角。这种设计使时间选择器看起来像一个可交互的元素,提高了用户体验。
时间选择器完成
);
}
时间选择器的完整实现提供了清晰的时间显示。在实际应用中,可以添加GestureDetector来实现点击时间选择器打开时间选择对话框的功能。
屏幕适配处理
在整个页面中,我们使用flutter_screenutil库来处理屏幕适配。.w表示宽度单位,.h表示高度单位,.sp表示字体大小单位。这样可以确保在不同屏幕尺寸的设备上,UI元素的大小和间距都能正确显示。
例如,EdgeInsets.all(16.w)表示四周都有16个宽度单位的边距。TextStyle(fontSize: 16.sp)表示字体大小为16个字体单位。
数据持久化
在实际应用中,通知设置应该保存到本地存储。可以使用SharedPreferences库来实现:
import 'package:shared_preferences/shared_preferences.dart';
void _saveNotificationSettings() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('soundEnabled', _soundEnabled);
await prefs.setBool('vibrationEnabled', _vibrationEnabled);
await prefs.setBool('popupEnabled', _popupEnabled);
await prefs.setBool('quietHoursEnabled', _quietHoursEnabled);
}
_saveNotificationSettings方法实现了通知设置的保存。首先获取SharedPreferences实例,然后使用setBool方法将各个开关状态保存到本地存储。这样可以确保用户的设置在应用重启后仍然保留。使用async/await语法使异步操作更加清晰易读。
加载设置
void _loadNotificationSettings() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_soundEnabled = prefs.getBool('soundEnabled') ?? true;
_vibrationEnabled = prefs.getBool('vibrationEnabled') ?? true;
_popupEnabled = prefs.getBool('popupEnabled') ?? true;
_quietHoursEnabled = prefs.getBool('quietHoursEnabled') ?? false;
});
}
_loadNotificationSettings方法实现了通知设置的加载。首先获取SharedPreferences实例,然后使用getBool方法从本地存储中读取各个开关状态。使用??操作符提供默认值,如果本地存储中没有保存该值,就使用默认值。通过setState更新UI,使加载的设置立即显示在页面上。这种设计确保了用户的设置能够正确地保存和恢复。
条件渲染
在夜间勿扰部分,我们使用if (_quietHoursEnabled)条件来控制时间选择器的显示。这是Flutter中常见的条件渲染模式。
if (_quietHoursEnabled) ...[
SizedBox(height: 12.h),
_buildTimeSelector('开始时间', '22:00'),
SizedBox(height: 12.h),
_buildTimeSelector('结束时间', '08:00'),
],
使用spread operator (…)可以将列表中的多个Widget展开到Column中。
总结
通知设置页面通过组合多个UI组件,为用户提供了一个完整的通知管理界面。使用Switch组件管理各个开关的状态,使用条件渲染来动态显示时间选择器。通过flutter_screenutil库,我们确保了UI在不同屏幕尺寸上的正确显示。
这个页面的设计遵循了Material Design的设计规范,使用了统一的颜色方案和间距。用户可以方便地自定义通知的方式和时间,提高了应用的易用性。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)