Flutter 每次不调用` of(context)`的本地化
我发现定位程序使用起来很麻烦。要显示本地化字符串,我必须调用Flutter 每次不调用` of(context)`的本地化,flutter,dart,Flutter,Dart,我发现定位程序使用起来很麻烦。要显示本地化字符串,我必须调用Localization.of(context).myAppTitle——在一个包含大量本地化字符串的大型嵌套小部件树中,这不是很流畅,也不容易浏览。更不用说它看起来很丑了 有没有办法让使用更方便?例如,我可以使用全局变量或带有本地化实例成员的静态类来简化访问吗?例如,声明顶级本地化变量 // Somewhere in the global scope Localization l; // main.dart class _MyAp
Localization.of(context).myAppTitle
——在一个包含大量本地化字符串的大型嵌套小部件树中,这不是很流畅,也不容易浏览。更不用说它看起来很丑了
有没有办法让使用更方便?例如,我可以使用全局变量或带有本地化
实例成员的静态类来简化访问吗?例如,声明顶级本地化变量
// Somewhere in the global scope
Localization l;
// main.dart
class _MyAppState extends State<MyApp>{
@override
void initState() {
super.initState();
getLocaleSomehow().then((locale){
l = Localization(locale);
setState((){});
});
}
}
所以从本质上说,我要问的是“不调用(上下文)
本地化的危险和/或缺点是什么?”
如果我真的需要使用(BuildContext)的.of
方法来访问本地化
实例,我至少可以将其存储在我的状态小部件中吗?我在想
class DetailsPage extends StatefulWidget{
Localization _l;
@override
Widget build(BuildContext context) {
_l = Localization.of(context);
// ... build widgets ...
}
}
或者有没有其他方法可以使本地化变得不那么麻烦?将本地化
对象存储在状态
中是完全可以的,在这种情况下效果非常好
如果只想让它看起来更漂亮,还可以在build方法中声明变量:
@覆盖
小部件构建(构建上下文){
最终l=本地化(上下文);
返回文本(l.myAppTitle);
}
在StatefulWidget
中,您还可以在中重新分配变量,或者使用空感知??=
运算符只分配一次,因为对象不会随时间而改变:
class\u MyStatefulWidgetState使用WidgetsBindingObserver扩展状态{
定位l;
@凌驾
didChangeDependencies(){
WidgetsBinding.instance.addObserver(这个);
l???=本地化(上下文);
super.didChangeDependencies();
}
@凌驾
无效区域设置(列表区域设置){
l=本地化(上下文);
super.didChangeLocales(locale);
}
@凌驾
处置{
WidgetsBinding.instance.removeObserver(此);
super.dispose();
}
@凌驾
小部件构建(BuildContext上下文)=>Text(l.myappite);
}
在didChangeLocales
中,您可以每次重新分配。这确保变量始终保持适当的区域设置,并在第一次生成时初始化(使用didChangeDependencies
)。请注意,我还包括了一个WidgetsBindingObserver
,您需要按照代码所示处理它。是的,它是必需的。
你可以解决这个问题,但这不是个好主意
原因是(Localization.of(context,T)
可能会随着时间的推移而更新。它确实存在的一些情况是:
- 地点改变了
- 已异步加载获取的本地化数据包
- MaterialApp/CupertinoApp更新了新的翻译版本
如果您没有正确地调用内部版本的本地化,那么在这些情况下,您的UI可能无法正确更新。您可以创建自己的文本小部件并在那里进行本地化。您可以用自己的MyText小部件替换所有文本小部件
class MyText extends StatelessWidget {
String data;
InlineSpan textSpan;
TextStyle style;
StrutStyle strutStyle;
TextAlign textAlign;
TextDirection textDirection;
Locale locale;
bool softWrap;
TextOverflow overflow;
double textScaleFactor;
int maxLines;
String semanticsLabel;
TextWidthBasis textWidthBasis;
MyText(
this.data, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
});
@override
Widget build(BuildContext context) {
return Text(
Localization.of(context).data,
style: style,
semanticsLabel: semanticsLabel,
locale: locale,
key: key,
textAlign: textAlign,
maxLines: maxLines,
overflow: overflow,
softWrap: softWrap,
strutStyle: strutStyle,
textDirection: textDirection,
textScaleFactor: textScaleFactor,
textWidthBasis: textWidthBasis,
);
}
}
谢谢,这正是我所怀疑的。但是,假设我不关心在用户更改设备区域设置时更改我的应用程序的语言(无需重新启动),是否仍然存在保留对本地化
实例的全局引用的危险?毕竟,我敢打赌,大多数用户在第一次安装设备后不会改变他们的区域设置……是的。正如我所说,当异步加载翻译时,也需要这样做。谢谢!我注意到还有一个didChangeLocales()
方法-使用它会比使用didChangeDependencies()
更好吗?@MagnusW您可以同时使用这两种方法。我在回答中补充了我的意思。谢谢,我只是在考虑是不是应该做那样的事情:-)
class MyText extends StatelessWidget {
String data;
InlineSpan textSpan;
TextStyle style;
StrutStyle strutStyle;
TextAlign textAlign;
TextDirection textDirection;
Locale locale;
bool softWrap;
TextOverflow overflow;
double textScaleFactor;
int maxLines;
String semanticsLabel;
TextWidthBasis textWidthBasis;
MyText(
this.data, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
});
@override
Widget build(BuildContext context) {
return Text(
Localization.of(context).data,
style: style,
semanticsLabel: semanticsLabel,
locale: locale,
key: key,
textAlign: textAlign,
maxLines: maxLines,
overflow: overflow,
softWrap: softWrap,
strutStyle: strutStyle,
textDirection: textDirection,
textScaleFactor: textScaleFactor,
textWidthBasis: textWidthBasis,
);
}
}