Flutter 中的远程配置设备语言更改
Remote Config Device Language Changes in Flutter
我遇到了一个问题,本地化工作正常,但应用程序需要 重新启动 才能更改 propagate .
方向改变
我知道 OrientationBuilder
,它会在检测到设备的 方向 发生变化时调用其构建器,例如Android 将被视为 配置 更改,就像设备语言更改一样。
语言变化
有没有类似LanguageBuilder
的东西?我自己找不到任何东西,在 flutter.io nor on pub. I have read this tutorial 上也找不到任何东西,我知道 Locale
,但我没有看到 Locale
的 Stream
。
我的问题是在 iOS 和 Android 中更改语言非常顺利。它会自动处理并与 Firebase Remote Config.
等服务完美集成
我真的很想知道是否有某种方法可以让我刷新我的本地化。
问题
所以我想问如何在设备语言更改时刷新我的远程配置。
不,Locale
没有Builder
。
相反,有一个 InheritedWidget
,您可以使用 Localizations.of
订阅它。
因为它是 InheritedWidget
,所有调用 Localizations.of
的小部件将在区域设置更改时自动刷新。
编辑 :
有关如何使用 Flutter Locale 系统实时重新加载文本的示例:
假设您有以下 class 包含翻译:
class MyData {
String title;
MyData({this.title});
}
然后您将拥有一个包含此类数据的 LocalizationsDelegate
。一个愚蠢的实现如下:
class MyLocale extends LocalizationsDelegate<MyData> {
MyData data;
MyLocale(this.data);
@override
bool isSupported(Locale locale) {
return true;
}
@override
Future<MyData> load(Locale locale) async {
return data;
}
@override
bool shouldReload(MyLocale old) {
return old.data != data;
}
}
要使用它,只需将它传递给 MaterialApp.localizationsDelegates
(一定要将 flutter_localizations
添加到您的 pubspec.yaml
):
LocalizationsDelegate myLocale = MyLocale(MyData(title: "Foo"));
...
MaterialApp(
localizationsDelegates: [
myLocale,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
);
然后您可以通过将 myLocale
替换为新的 MyLocale
实例来自由地实时重新加载您的翻译。
这是点击计数器应用程序的完整示例。但是当前计数存储在 Locale
中(因为为什么不呢?)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
class MyCount {
String count;
MyCount({this.count});
}
class MyCountLocale extends LocalizationsDelegate<MyCount> {
MyCount data;
MyCountLocale(this.data);
@override
bool isSupported(Locale locale) {
return true;
}
@override
Future<MyCount> load(Locale locale) async {
return data;
}
@override
bool shouldReload(MyCountLocale old) {
return old.data != data;
}
}
Future<void> main() async {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ValueNotifier<int> count = ValueNotifier<int>(0);
LocalizationsDelegate myLocale;
@override
void initState() {
count.addListener(() {
setState(() {
myLocale = MyCountLocale(MyCount(count: count.value.toString()));
});
});
myLocale = MyCountLocale(MyCount(count: count.value.toString()));
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
myLocale,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: MyHomePage(count: count),
);
}
}
class MyHomePage extends StatefulWidget {
final ValueNotifier<int> count;
MyHomePage({this.count});
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
primary: true,
appBar: AppBar(),
body: Column(
children: <Widget>[
FloatingActionButton(
onPressed: () => widget.count.value++,
child: Icon(Icons.plus_one),
),
ListTile(
title: Text(Localizations.of<MyCount>(context, MyCount).count),
),
],
),
);
}
}
设备语言更改 可以使用 WidgetsBindingObserver
.
检测到
在你的State
(with WidgetsBindingObserver
)中加上StatefulWidget
是最简单的:
class _MyWidgetState extends State<MyWidget> with WidgetsBindingObserver {
@override
void didChangeLocales(List<Locale> locale) {
// The device language was changed when this is called.
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
...
}
这意味着您现在可以重新加载您的RemoteConfig
in didChangeLocales
:
@override
void didChangeLocales(List<Locale> locale) {
_updateRemoteConfig();
}
Future<void> _updateRemoteConfig() async {
final remoteConfig = await RemoteConfig.instance;
await remoteConfig.activateFetched(); // This will apply the new locale.
}
我遇到了一个问题,本地化工作正常,但应用程序需要 重新启动 才能更改 propagate .
方向改变
我知道 OrientationBuilder
,它会在检测到设备的 方向 发生变化时调用其构建器,例如Android 将被视为 配置 更改,就像设备语言更改一样。
语言变化
有没有类似LanguageBuilder
的东西?我自己找不到任何东西,在 flutter.io nor on pub. I have read this tutorial 上也找不到任何东西,我知道 Locale
,但我没有看到 Locale
的 Stream
。
我的问题是在 iOS 和 Android 中更改语言非常顺利。它会自动处理并与 Firebase Remote Config.
等服务完美集成我真的很想知道是否有某种方法可以让我刷新我的本地化。
问题
所以我想问如何在设备语言更改时刷新我的远程配置。
不,Locale
没有Builder
。
相反,有一个 InheritedWidget
,您可以使用 Localizations.of
订阅它。
因为它是 InheritedWidget
,所有调用 Localizations.of
的小部件将在区域设置更改时自动刷新。
编辑 :
有关如何使用 Flutter Locale 系统实时重新加载文本的示例:
假设您有以下 class 包含翻译:
class MyData {
String title;
MyData({this.title});
}
然后您将拥有一个包含此类数据的 LocalizationsDelegate
。一个愚蠢的实现如下:
class MyLocale extends LocalizationsDelegate<MyData> {
MyData data;
MyLocale(this.data);
@override
bool isSupported(Locale locale) {
return true;
}
@override
Future<MyData> load(Locale locale) async {
return data;
}
@override
bool shouldReload(MyLocale old) {
return old.data != data;
}
}
要使用它,只需将它传递给 MaterialApp.localizationsDelegates
(一定要将 flutter_localizations
添加到您的 pubspec.yaml
):
LocalizationsDelegate myLocale = MyLocale(MyData(title: "Foo"));
...
MaterialApp(
localizationsDelegates: [
myLocale,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
);
然后您可以通过将 myLocale
替换为新的 MyLocale
实例来自由地实时重新加载您的翻译。
这是点击计数器应用程序的完整示例。但是当前计数存储在 Locale
中(因为为什么不呢?)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
class MyCount {
String count;
MyCount({this.count});
}
class MyCountLocale extends LocalizationsDelegate<MyCount> {
MyCount data;
MyCountLocale(this.data);
@override
bool isSupported(Locale locale) {
return true;
}
@override
Future<MyCount> load(Locale locale) async {
return data;
}
@override
bool shouldReload(MyCountLocale old) {
return old.data != data;
}
}
Future<void> main() async {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ValueNotifier<int> count = ValueNotifier<int>(0);
LocalizationsDelegate myLocale;
@override
void initState() {
count.addListener(() {
setState(() {
myLocale = MyCountLocale(MyCount(count: count.value.toString()));
});
});
myLocale = MyCountLocale(MyCount(count: count.value.toString()));
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
myLocale,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: MyHomePage(count: count),
);
}
}
class MyHomePage extends StatefulWidget {
final ValueNotifier<int> count;
MyHomePage({this.count});
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
primary: true,
appBar: AppBar(),
body: Column(
children: <Widget>[
FloatingActionButton(
onPressed: () => widget.count.value++,
child: Icon(Icons.plus_one),
),
ListTile(
title: Text(Localizations.of<MyCount>(context, MyCount).count),
),
],
),
);
}
}
设备语言更改 可以使用 WidgetsBindingObserver
.
在你的State
(with WidgetsBindingObserver
)中加上StatefulWidget
是最简单的:
class _MyWidgetState extends State<MyWidget> with WidgetsBindingObserver {
@override
void didChangeLocales(List<Locale> locale) {
// The device language was changed when this is called.
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
...
}
这意味着您现在可以重新加载您的RemoteConfig
in didChangeLocales
:
@override
void didChangeLocales(List<Locale> locale) {
_updateRemoteConfig();
}
Future<void> _updateRemoteConfig() async {
final remoteConfig = await RemoteConfig.instance;
await remoteConfig.activateFetched(); // This will apply the new locale.
}