From e7c1e333550c7a7ae8ee23a7f9a6bc5ba5b42515 Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 3 Mar 2026 19:39:07 -0800 Subject: [PATCH] =?UTF-8?q?fix(genex-mobile):=20=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E5=81=8F=E5=A5=BD=E6=8C=81=E4=B9=85=E5=8C=96=20=E2=80=94=20?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E9=80=89=E6=8B=A9=E4=B8=8D=E5=86=8D=E5=9B=A0?= =?UTF-8?q?=E9=87=8D=E5=90=AF=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 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 --- .../lib/app/i18n/locale_manager.dart | 45 ++++++++++++++++++- .../presentation/pages/settings_page.dart | 2 +- frontend/genex-mobile/lib/main.dart | 3 ++ frontend/genex-mobile/pubspec.yaml | 1 + 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/frontend/genex-mobile/lib/app/i18n/locale_manager.dart b/frontend/genex-mobile/lib/app/i18n/locale_manager.dart index c75ea98..864ea36 100644 --- a/frontend/genex-mobile/lib/app/i18n/locale_manager.dart +++ b/frontend/genex-mobile/lib/app/i18n/locale_manager.dart @@ -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 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 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 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? systemLocales, Iterable 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; + } } diff --git a/frontend/genex-mobile/lib/features/profile/presentation/pages/settings_page.dart b/frontend/genex-mobile/lib/features/profile/presentation/pages/settings_page.dart index 08dbd38..860f4b0 100644 --- a/frontend/genex-mobile/lib/features/profile/presentation/pages/settings_page.dart +++ b/frontend/genex-mobile/lib/features/profile/presentation/pages/settings_page.dart @@ -269,7 +269,7 @@ class _SettingsPageState extends State { color: AppColors.primary, size: 22) : null, onTap: () { - LocaleManager.userLocale.value = locale; + LocaleManager.setLocale(locale); setState(() {}); Navigator.pop(context); }, diff --git a/frontend/genex-mobile/lib/main.dart b/frontend/genex-mobile/lib/main.dart index 466325e..5df7989 100644 --- a/frontend/genex-mobile/lib/main.dart +++ b/frontend/genex-mobile/lib/main.dart @@ -52,6 +52,9 @@ Future main() async { // 初始化通知徽章管理器 NotificationBadgeManager().initialize(); + // 恢复用户语言偏好(无选择时跟随系统语言) + await LocaleManager.init(); + runApp(const GenexConsumerApp()); } diff --git a/frontend/genex-mobile/pubspec.yaml b/frontend/genex-mobile/pubspec.yaml index b61e74a..35b6aa1 100644 --- a/frontend/genex-mobile/pubspec.yaml +++ b/frontend/genex-mobile/pubspec.yaml @@ -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: