如何通过Flutter_localizations与Bloc实现Flutter应用语言的永久切换?
解决方案:实现Flutter多语言持久化(基于Bloc和flutter_localizations)
先直接解决你的核心问题:关闭重启后语言重置,是因为当前代码没有持久化用户选择的语言。下面是完整的修改方案,同时解答你的疑问。
核心修改思路
- 用
SharedPreferences存储用户选择的语言(轻量级键值存储,适合这类简单配置) - 应用启动时优先读取存储的语言,没有则用默认英文
- 修改Bloc逻辑,切换语言时同步保存到本地存储
修改后的完整代码
首先确保在pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter bloc: ^8.1.0 flutter_bloc: ^8.1.0 shared_preferences: ^2.2.0
1. 初始化逻辑(main函数)
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; // 导入你的AppLocalizations类 void main() async { // 必须提前初始化Flutter绑定,才能在runApp前执行异步操作 WidgetsFlutterBinding.ensureInitialized(); // 读取本地存储的语言配置 final prefs = await SharedPreferences.getInstance(); final savedLangCode = prefs.getString('selected_language'); // 设置初始语言:有存储值用存储值,无则默认英文 Locale initialLocale = savedLangCode != null ? Locale(savedLangCode, '') : const Locale('en', ''); runApp(MyApp(initialLocale: initialLocale)); }
2. MyApp组件
class MyApp extends StatelessWidget { final Locale initialLocale; const MyApp({Key? key, required this.initialLocale}) : super(key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => LanguageCubit(initialLocale), child: BlocBuilder<LanguageCubit, Locale>(builder: (context, lang) { return MaterialApp( locale: lang, title: 'Localizations Sample App', localizationsDelegates: const [ AppLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('en', ''), Locale('es', ''), Locale('tr', ''), Locale('it', ''), ], home: const Home(), ); }), ); } }
3. LanguageCubit(加入持久化逻辑)
class LanguageCubit extends Cubit<Locale> { LanguageCubit(Locale initialLocale) : super(initialLocale); static final _languageEn = const Locale('en', ''); static final _languageEs = const Locale('es', ''); static final _languageTr = const Locale('tr', ''); static final _languageIt = const Locale('it', ''); // 切换英文并保存 Future<void> changeLangEn() async { await _saveLanguage('en'); emit(_languageEn); } // 切换西班牙文并保存 Future<void> changeLangEs() async { await _saveLanguage('es'); emit(_languageEs); } // 切换土耳其文并保存 Future<void> changeLangTr() async { await _saveLanguage('tr'); emit(_languageTr); } // 切换意大利文并保存 Future<void> changeLangIt() async { await _saveLanguage('it'); emit(_languageIt); } // 私有方法:保存语言到本地存储 Future<void> _saveLanguage(String langCode) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString('selected_language', langCode); } }
4. Home页面(扩展多语言切换按钮)
class Home extends StatelessWidget { const Home({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Container( color: Colors.amberAccent, width: 200, height: 300, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(AppLocalizations.of(context).helloWorld, style: const TextStyle(fontSize: 18)), const Divider(height: 20), TextButton( onPressed: () => context.read<LanguageCubit>().changeLangEn(), child: const Text('English')), TextButton( onPressed: () => context.read<LanguageCubit>().changeLangEs(), child: const Text('Español')), TextButton( onPressed: () => context.read<LanguageCubit>().changeLangTr(), child: const Text('Türkçe')), TextButton( onPressed: () => context.read<LanguageCubit>().changeLangIt(), child: const Text('Italiano')), ], ), ), ), ); } }
你的疑问解答
1. 是否需要将选中的语言存储到数据库等存储介质?
不需要。语言选择是单个字符串的简单配置,用SharedPreferences完全足够——它是Flutter官方提供的轻量级键值对存储,操作简单、性能好,适合保存这类用户偏好设置。只有当你需要存储复杂结构化数据时,才考虑用Hive、SQFlite等数据库。
2. Flutter_localizations是否提供了简便的实现方式?
不提供。flutter_localizations的核心职责是加载本地化资源、适配系统语言规则、提供国际化组件支持,它并不包含持久化用户选择语言的逻辑。持久化需要我们结合本地存储方案(比如上面用的SharedPreferences)自行实现。
内容的提问来源于stack exchange,提问作者Raghim Najafov
相关产品推荐
相关产品推荐

