Flutter Localizations实时切换问题:基于Riverpod实现语言即时更新
即时切换Flutter语言(适配Riverpod)
核心思路
用Riverpod维护当前语言的可监听状态,切换语言时更新状态并同步缓存,同时让App的本地化配置响应状态变化,实现即时刷新。
1. 创建语言状态管理Provider
写一个LanguageNotifier处理语言状态的读取、切换和缓存逻辑,再通过StateNotifierProvider暴露给全局使用:
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; // 定义支持的语言列表 const supportedLocales = [ Locale('zh', 'CN'), Locale('en', 'US'), ]; // 默认语言 const defaultLocale = Locale('zh', 'CN'); class LanguageNotifier extends StateNotifier<Locale> { LanguageNotifier() : super(defaultLocale) { _loadSavedLanguage(); } // 从shared_preferences读取缓存语言 Future<void> _loadSavedLanguage() async { final prefs = await SharedPreferences.getInstance(); final savedLangCode = prefs.getString('selected_language_code'); final savedCountryCode = prefs.getString('selected_country_code'); if (savedLangCode != null && savedCountryCode != null) { state = Locale(savedLangCode, savedCountryCode); } } // 切换语言并保存到缓存 Future<void> switchLanguage(Locale newLocale) async { state = newLocale; final prefs = await SharedPreferences.getInstance(); await prefs.setString('selected_language_code', newLocale.languageCode); await prefs.setString('selected_country_code', newLocale.countryCode!); } } // 全局可访问的语言Provider final languageProvider = StateNotifierProvider<LanguageNotifier, Locale>((ref) { return LanguageNotifier(); });
2. 修改main.dart,让MaterialApp响应语言状态
用Consumer包裹MaterialApp,监听语言Provider的状态变化,动态更新locale:
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; // 导入上面的语言Provider文件 void main() { runApp(const ProviderScope(child: MyApp())); } class MyApp extends ConsumerWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // 实时获取当前语言状态 final currentLocale = ref.watch(languageProvider); return MaterialApp( title: 'Language Demo', locale: currentLocale, supportedLocales: supportedLocales, localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, // 这里添加你的自定义本地化delegate ], home: const LanguageSelectorPage(), ); } }
3. 在selector.dart中实现切换逻辑
在语言选择页面,调用Provider的switchLanguage方法即可触发即时切换:
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; // 导入语言Provider文件 class LanguageSelectorPage extends ConsumerWidget { const LanguageSelectorPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return Scaffold( appBar: AppBar(title: const Text('选择语言')), body: ListView( children: [ ListTile( title: const Text('中文'), onTap: () { ref.read(languageProvider.notifier).switchLanguage(const Locale('zh', 'CN')); Navigator.pop(context); }, ), ListTile( title: const Text('English'), onTap: () { ref.read(languageProvider.notifier).switchLanguage(const Locale('en', 'US')); Navigator.pop(context); }, ), ], ), ); } }
关键注意点
- 确保你的本地化资源(比如intl包的arb文件)已正确配置,能匹配对应locale的文本
- 自定义LocalizationsDelegate要能正确响应locale变化
- 必须用
ConsumerWidget或Consumer包裹依赖语言状态的部件,确保状态更新时自动重建
内容的提问来源于stack exchange,提问作者AurimasKl
相关产品推荐
相关产品推荐

