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: