如何使用 Provider 实现 Flutter 本地化?
Posted
技术标签:
【中文标题】如何使用 Provider 实现 Flutter 本地化?【英文标题】:How to implement Flutter Localization with Provider? 【发布时间】:2020-12-17 06:47:34 【问题描述】:我想让我的应用程序以 2 种不同的语言运行。 我想问题是我无法在 multiprovider 中处理 Cosumer ,可能吗?
我正在使用flutter_localization 包和flutter 提供程序包;
这是我的代码:
void main() async
WidgetsFlutterBinding.ensureInitialized();
AppLanguage appLanguage = AppLanguage();
await appLanguage.fetchLocale();
SharedPreferences.getInstance().then((prefs)
var darkModeOn = prefs.getBool('darkMode') ?? true;
runApp(
ChangeNotifierProvider<ThemeManager>(
builder: (_) => ThemeManager(lightTheme),
child: MyApp(appLanguage: appLanguage),
),
);
);
分类我的应用
class MyApp extends StatelessWidget
final AppLanguage appLanguage;
MyApp(this.appLanguage);
@override
Widget build(BuildContext context)
final themeNotifier = Provider.of<ThemeManager>(context);
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: ApiService()),
ChangeNotifierProxyProvider<ApiService, StudentData>(
builder: (ctx, auth, _) => StudentData(auth.token, auth.school),
)
],
child: Consumer<ApiService>(
builder: (ctx, auth, _) => ChangeNotifierProvider<AppLanguage>(
builder: (_) => appLanguage,
child: Consumer<AppLanguage>(
builder: (context, model, child) => MaterialApp(
locale: appLanguage.appLocal,
supportedLocales: [Locale('ru', 'RU'), Locale('uz', 'UZ')],
localizationsDelegates: [
AppLocalization.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
debugShowCheckedModeBanner: false,
title: "Socratus |Mobile",
theme: themeNotifier.getTheme(),
home: auth.isAuth
? MainScreen()
: FutureBuilder(
future: auth.tryAutoLogin(),
builder: (ctx, authResultSnapshot) => LoginScreen()),
routes:
MainScreen.routeName: (ctx) => MainScreen(),
ProfilePage.routeName: (ctx) => ProfilePage(),
SettingsPage.routeName: (ctx) => SettingsPage(
appLanguage: appLanguage,
),
ChangePassword.routeName: (ctx) => ChangePassword(),
HomeworkScreen.routeName: (ctx) => HomeworkScreen(),
HWDetails.routeName: (ctx) => HWDetails(),
NewsPage.routeName: (ctx) => NewsPage(),
QuestionAndAnswers.routeName: (ctx) => QuestionAndAnswers(),
MyDownloads.routeName: (ctx) => MyDownloads(),
,
),
),
),
),
);
这是我尝试实现的方式
class AppLocalization
final Locale locale;
AppLocalization(this.locale);
static AppLocalization of(BuildContext context)
return Localizations.of<AppLocalization>(context, AppLocalization);
static const LocalizationsDelegate<AppLocalization> delegate =
_AppLocalizationDelegate();
Map<String, String> _localizedStrings;
Future<bool> load() async
String jsonString = await rootBundle
.loadString('assets/translations/$locale.languageCode.json');
Map<String, dynamic> jsonMap = json.decode(jsonString);
_localizedStrings = jsonMap.map((key, value)
return MapEntry(key, value.toString());
);
return true;
String translate(String key)
return _localizedStrings[key];
class _AppLocalizationDelegate extends LocalizationsDelegate<AppLocalization>
// This delegate instance will never change (it doesn't even have fields!)
// It can provide a constant constructor.
const _AppLocalizationDelegate();
@override
bool isSupported(Locale locale)
// Include all of your supported language codes here
return ['ru', 'uz'].contains(locale.languageCode);
@override
Future<AppLocalization> load(Locale locale) async
AppLocalization localizations = new AppLocalization(locale);
await localizations.load();
return localizations;
@override
bool shouldReload(_AppLocalizationDelegate old) => false;
还有我的提供者:
class AppLanguage extends ChangeNotifier
Locale _appLocale = Locale('ru');
Locale get appLocal => _appLocale ?? Locale("ru");
fetchLocale() async
var prefs = await SharedPreferences.getInstance();
if (prefs.getString('language_code') == null)
_appLocale = Locale('ru');
return Null;
_appLocale = Locale(prefs.getString('language_code'));
return Null;
void changeLanguage(Locale type) async
var prefs = await SharedPreferences.getInstance();
if (_appLocale == type)
return;
if (type == Locale("uz"))
_appLocale = Locale("uz");
await prefs.setString('language_code', 'uz');
await prefs.setString('countryCode', 'UZ');
else
_appLocale = Locale("ru");
await prefs.setString('language_code', 'ru');
await prefs.setString('countryCode', 'RU');
notifyListeners();
如果这不是正确的方法,我该如何实现这个功能?
【问题讨论】:
【参考方案1】:this article 中解释了您尝试实施的方式,如果您想要不同的方法,我建议您查看 pub.dev 中的Easy Localization,它目前处理所有Flutter internationalization features .
【讨论】:
以上是关于如何使用 Provider 实现 Flutter 本地化?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:如何设置 Stream 和 Provider