fix(genex-mobile): 语言偏好持久化 — 用户选择不再因重启丢失
修复 LocaleManager 仅用内存 ValueNotifier 存储语言选择的问题, 重启 App 后用户选的语言会丢失,回退到系统语言。 改动: - pubspec.yaml: 添加 shared_preferences 依赖 - locale_manager.dart: 新增 init() 启动恢复 + setLocale() 写入持久化 · null = 跟随系统语言(清除 SP 记录) · 非 null = 持久化到 SharedPreferences,重启后自动恢复 - main.dart: 启动时调用 await LocaleManager.init() - settings_page.dart: 语言选择改用 LocaleManager.setLocale() 行为:首次安装跟随系统语言 → 用户选择后持久化 → 重启保持不变 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0cd5c58ecb
commit
e7c1e33355
|
|
@ -1,12 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// 全局语言状态管理
|
||||
///
|
||||
/// userLocale = null 时跟随系统语言
|
||||
/// 用户在设置页选择后,设置为具体 Locale
|
||||
/// 用户在设置页选择后,持久化到 SharedPreferences,下次启动自动恢复
|
||||
class LocaleManager {
|
||||
static final ValueNotifier<Locale?> userLocale = ValueNotifier(null);
|
||||
|
||||
static const _prefKey = 'user_locale';
|
||||
|
||||
static const supportedLocales = [
|
||||
Locale('zh', 'CN'),
|
||||
Locale('zh', 'TW'),
|
||||
|
|
@ -14,6 +17,29 @@ class LocaleManager {
|
|||
Locale('ja'),
|
||||
];
|
||||
|
||||
/// 启动时调用,从 SharedPreferences 恢复用户选择的语言
|
||||
static Future<void> init() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final saved = prefs.getString(_prefKey);
|
||||
if (saved != null) {
|
||||
final locale = _parseLocale(saved);
|
||||
if (locale != null) {
|
||||
userLocale.value = locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 设置用户语言并持久化(传 null 表示恢复跟随系统)
|
||||
static Future<void> setLocale(Locale? locale) async {
|
||||
userLocale.value = locale;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
if (locale == null) {
|
||||
await prefs.remove(_prefKey);
|
||||
} else {
|
||||
await prefs.setString(_prefKey, _serializeLocale(locale));
|
||||
}
|
||||
}
|
||||
|
||||
/// 根据系统 locale 解析最佳匹配
|
||||
static Locale resolve(List<Locale>? systemLocales, Iterable<Locale> supported) {
|
||||
if (systemLocales == null || systemLocales.isEmpty) {
|
||||
|
|
@ -71,4 +97,21 @@ class LocaleManager {
|
|||
return locale.toString();
|
||||
}
|
||||
}
|
||||
|
||||
static String _serializeLocale(Locale locale) {
|
||||
if (locale.countryCode != null && locale.countryCode!.isNotEmpty) {
|
||||
return '${locale.languageCode}_${locale.countryCode}';
|
||||
}
|
||||
return locale.languageCode;
|
||||
}
|
||||
|
||||
static Locale? _parseLocale(String str) {
|
||||
final parts = str.split('_');
|
||||
if (parts.length == 2) {
|
||||
return Locale(parts[0], parts[1]);
|
||||
} else if (parts.length == 1 && parts[0].isNotEmpty) {
|
||||
return Locale(parts[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
color: AppColors.primary, size: 22)
|
||||
: null,
|
||||
onTap: () {
|
||||
LocaleManager.userLocale.value = locale;
|
||||
LocaleManager.setLocale(locale);
|
||||
setState(() {});
|
||||
Navigator.pop(context);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ Future<void> main() async {
|
|||
// 初始化通知徽章管理器
|
||||
NotificationBadgeManager().initialize();
|
||||
|
||||
// 恢复用户语言偏好(无选择时跟随系统语言)
|
||||
await LocaleManager.init();
|
||||
|
||||
runApp(const GenexConsumerApp());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ dependencies:
|
|||
firebase_core: ^3.4.0
|
||||
flutter_local_notifications: ^18.0.0
|
||||
in_app_update: ^4.2.2
|
||||
shared_preferences: ^2.2.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue