在移动应用开发中,用户管理模块是任何需要用户账户系统的应用的核心组件。本文将详细介绍如何使用Flutter框架为OpenHarmony平台构建一个轻量级开源记事本应用的用户管理界面。这个模块不仅需要展示用户信息,还要提供便捷的操作入口和个性化设置选项。
用户管理系统的设计遵循三个核心原则:
实现用户管理功能需要以下几个关键依赖包:
dart复制import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:shared_preferences/shared_preferences.dart';
提示:在实际项目中,建议使用GetX的最新稳定版本,以获得最佳的性能和功能支持。
用户管理页面采用StatelessWidget设计,因为页面状态由GetX控制器管理:
dart复制class UserManagementPage extends StatelessWidget {
const UserManagementPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('用户管理'),
actions: [
IconButton(
icon: const Icon(Icons.edit),
onPressed: () => _editUserProfile(),
),
],
),
body: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
_buildUserProfileCard(),
SizedBox(height: 16.h),
_buildUsageStatisticsCard(),
SizedBox(height: 16.h),
_buildSettingsCard(),
],
),
),
);
}
}
页面内容分为三个主要模块:
这种模块化设计有以下优势:
使用Material Design的Card组件作为基础容器:
dart复制Widget _buildUserProfileCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 头像和信息行
Row(
children: [
CircleAvatar(
radius: 40.r,
backgroundColor: const Color(0xFF2196F3),
child: Icon(
Icons.person,
size: 40.sp,
color: Colors.white,
),
),
SizedBox(width: 16.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'用户名',
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey[600],
),
),
SizedBox(height: 4.h),
Text(
'Demo User',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4.h),
Text(
'demo@example.com',
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey[600],
),
),
],
),
),
],
),
SizedBox(height: 16.h),
// 时间信息行
Row(
children: [
Expanded(
child: _InfoItem(
icon: Icons.calendar_today,
label: '注册时间',
value: '2024-01-01',
),
),
Expanded(
child: _InfoItem(
icon: Icons.access_time,
label: '最后登录',
value: '2024-01-15 14:30',
),
),
],
),
],
),
),
);
}
创建_InfoItem组件用于展示标签-值对:
dart复制class _InfoItem extends StatelessWidget {
final IconData icon;
final String label;
final String value;
const _InfoItem({
required this.icon,
required this.label,
required this.value,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
icon,
size: 16.sp,
color: Colors.grey[600],
),
SizedBox(width: 8.w),
Text(
label,
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey[600],
),
),
],
),
SizedBox(height: 4.h),
Text(
value,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
),
),
],
);
}
}
dart复制Widget _buildUsageStatisticsCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'使用统计',
style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: _StatItem(
title: '总笔记数',
value: '156',
icon: Icons.note,
color: Colors.blue,
),
),
Expanded(
child: _StatItem(
title: '总字数',
value: '45,280',
icon: Icons.text_fields,
color: Colors.green,
),
),
],
),
SizedBox(height: 12.h),
Row(
children: [
Expanded(
child: _StatItem(
title: '收藏数',
value: '23',
icon: Icons.star,
color: Colors.amber,
),
),
Expanded(
child: _StatItem(
title: '分类数',
value: '8',
icon: Icons.folder,
color: Colors.purple,
),
),
],
),
SizedBox(height: 12.h),
Row(
children: [
Expanded(
child: _StatItem(
title: '使用天数',
value: '15',
icon: Icons.date_range,
color: Colors.red,
),
),
Expanded(
child: _StatItem(
title: '日均笔记',
value: '10.4',
icon: Icons.trending_up,
color: Colors.teal,
),
),
],
),
],
),
),
);
}
dart复制class _StatItem extends StatelessWidget {
final String title;
final String value;
final IconData icon;
final Color color;
const _StatItem({
required this.title,
required this.value,
required this.icon,
required this.color,
});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Icon(
icon,
size: 24.sp,
color: color,
),
SizedBox(height: 8.h),
Text(
value,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: color,
),
),
SizedBox(height: 4.h),
Text(
title,
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey[600],
),
),
],
),
);
}
}
dart复制Widget _buildSettingsCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'应用设置',
style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 16.h),
ListTile(
leading: const Icon(Icons.notifications),
title: const Text('通知设置'),
subtitle: const Text('管理应用通知偏好'),
trailing: const Icon(Icons.arrow_forward_ios),
onTap: () => _navigateToNotificationSettings(),
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.privacy_tip),
title: const Text('隐私设置'),
subtitle: const Text('管理数据和隐私选项'),
trailing: const Icon(Icons.arrow_forward_ios),
onTap: () => _navigateToPrivacySettings(),
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.storage),
title: const Text('存储管理'),
subtitle: const Text('查看和管理应用存储'),
trailing: const Icon(Icons.arrow_forward_ios),
onTap: () => _navigateToStorageManagement(),
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.info),
title: const Text('关于应用'),
subtitle: const Text('查看应用信息和版本'),
trailing: const Icon(Icons.arrow_forward_ios),
onTap: () => _navigateToAboutPage(),
),
],
),
),
);
}
dart复制void _editUserProfile() {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('编辑资料'),
content: SizedBox(
width: 300.w,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: const InputDecoration(
labelText: '用户名',
border: OutlineInputBorder(),
),
initialValue: 'Demo User',
),
SizedBox(height: 16.h),
TextField(
decoration: const InputDecoration(
labelText: '邮箱',
border: OutlineInputBorder(),
),
initialValue: 'demo@example.com',
),
SizedBox(height: 16.h),
TextField(
decoration: const InputDecoration(
labelText: '个人简介',
border: OutlineInputBorder(),
),
maxLines: 3,
initialValue: '这是我的个人简介',
),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
ElevatedButton(
onPressed: () {
_saveUserProfile();
Navigator.pop(context);
Get.snackbar('成功', '资料已更新');
},
child: const Text('保存'),
),
],
),
);
}
dart复制Future<void> _saveUserProfile() async {
final prefs = await SharedPreferences.getInstance();
// 这里应该将用户资料保存到数据库或服务器
await prefs.setString('user_name', 'Demo User');
await prefs.setString('user_email', 'demo@example.com');
await prefs.setString('user_bio', '这是我的个人简介');
// 通知其他页面用户资料已更新
Get.find<UserController>().updateUserProfile();
}
dart复制class UserController extends GetxController {
var userName = ''.obs;
var userEmail = ''.obs;
var userBio = ''.obs;
var isLoggedIn = false.obs;
Future<void> loadUserProfile() async {
final prefs = await SharedPreferences.getInstance();
userName.value = prefs.getString('user_name') ?? '';
userEmail.value = prefs.getString('user_email') ?? '';
userBio.value = prefs.getString('user_bio') ?? '';
isLoggedIn.value = prefs.getBool('is_logged_in') ?? false;
}
Future<void> updateUserProfile() async {
await loadUserProfile();
}
Future<void> logout() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('is_logged_in', false);
isLoggedIn.value = false;
Get.offAll(() => const LoginPage());
}
}
在应用启动时初始化控制器:
dart复制void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化GetX控制器
Get.put(UserController());
// 加载用户资料
await Get.find<UserController>().loadUserProfile();
runApp(const MyApp());
}
dart复制class ThemedUserManagementPage extends StatelessWidget {
const ThemedUserManagementPage({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
backgroundColor: theme.scaffoldBackgroundColor,
appBar: AppBar(
backgroundColor: theme.appBarTheme.backgroundColor,
title: Text(
'用户管理',
style: TextStyle(color: theme.textTheme.titleLarge?.color),
),
iconTheme: IconThemeData(color: theme.appBarTheme.iconTheme?.color),
actions: [
IconButton(
icon: Icon(
Icons.edit,
color: theme.appBarTheme.iconTheme?.color,
),
onPressed: () => _editUserProfile(),
),
],
),
body: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
_buildThemedUserProfileCard(theme),
SizedBox(height: 16.h),
_buildThemedUsageStatisticsCard(theme),
SizedBox(height: 16.h),
_buildThemedSettingsCard(theme),
],
),
),
);
}
}
SharedPreferences读取为null:
GetX状态不更新:
屏幕适配问题:
在实际开发中,我发现合理使用GetX的状态管理可以显著简化开发流程,特别是在需要跨组件共享状态的场景下。同时,ScreenUtil的屏幕适配方案在OpenHarmony设备上表现良好,能够有效应对不同设备的显示需求。