我发现使用the official Flutter localization plugin很麻烦。要显示本地化的字符串,我必须调用Localization.of(context).myAppTitle
-在具有大量本地化字符串的巨大嵌套小部件树中,它并不是完全圆滑或容易浏览。更不用说它看起来丑陋了。
有没有一种方法可以使用法更好?例如,是否可以将全局变量或静态类与Localization
实例成员一起使用来简化访问?例如,声明一个顶级Localization
变量
// 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((){});
});
}
}
那我可以简单地打电话
Text(l.myAppTitle)
因此,从本质上讲,我要问的是“不打Localization.of(context)
有什么危险和/或缺点?”
如果确实需要使用.of(BuildContext)
方法来访问Localization
实例-是否可以至少将其存储在StatefulWidget
中?我在想类似的东西
class DetailsPage extends StatefulWidget{
Localization _l;
@override
Widget build(BuildContext context) {
_l = Localization.of(context);
// ... build widgets ...
}
}
还是有其他方法可以减少本地化的麻烦?
答案 0 :(得分:1)
是的,这是必需的。 您可以解决它,但这是一个坏主意。
这样做的原因是Localization.of<T>(context, T)
可能会随着时间更新。确实有以下几种情况:
如果您没有按照需要在 build 内部正确调用Localization.of
,则在这些情况下,您的UI可能无法正确更新。
答案 1 :(得分:0)
将Localization
对象存储在State
内是完全可以的,并且在这种情况下效果很好。
如果只想让它看起来更好,还可以在build方法中声明变量:
@override
Widget build(BuildContext context) {
final l = Localization.of(context);
return Text(l.myAppTitle);
}
在StatefulWidget
中,您也可以在didChangeDependencies
中重新分配变量,或者仅使用具有null感知功能的??=
赋值一次,因为对象不会随着时间变化:
class _MyStatefulWidgetState extends State<MyStatefulWidget> with WidgetsBindingObserver {
Localization l;
@override
didChangeDependencies() {
WidgetsBinding.instance.addObserver(this);
l ??= Localization.of(context);
super.didChangeDependencies();
}
@override
void didChangeLocales(List<Locale> locale) {
l = Localization.of(context);
super.didChangeLocales(locale);
}
@override
dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) => Text(l.myAppTite);
}
在didChangeLocales
中,您可以每次重新分配。这样可以确保变量始终保持适当的语言环境,并在首次构建时使用didChangeDependencies
进行初始化。请注意,我还包括一个WidgetsBindingObserver
,您需要按照代码中的说明进行处理。
答案 2 :(得分:0)
您可以创建自己的文本小部件并在那里进行本地化。您可以将所有文本小部件替换为自己的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,
);
}
}