我发现使用官方 Flutter 本地化插件的本地化过程很麻烦。要显示我必须调用的本地化字符串Localization.of(context).myAppTitle
- 在具有大量本地化字符串的巨大嵌套 Widget 树中并不完全光滑或易于浏览。更不用说它看起来很丑。
有没有办法让使用更好?例如,我可以使用全局变量或带有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((){});
});
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以简单地打电话
Text(l.myAppTitle)
Run Code Online (Sandbox Code Playgroud)
所以从本质上讲,我要问的是“不打电话有Localization.of(context)
什么危险和/或缺点?”
如果我真的需要使用该.of(BuildContext)
方法来访问Localization
实例 - 我至少可以将它存储在我的StatefulWidget
? 我在想像
class DetailsPage extends StatefulWidget{
Localization _l;
@override
Widget build(BuildContext context) {
_l = Localization.of(context);
// ... build widgets ...
}
}
Run Code Online (Sandbox Code Playgroud)
或者有没有其他方法可以让本地化不那么麻烦?
我将这里其他回复(特别是 Fleximex 的)的一些信息结合到一个我发现非常有趣的解决方案中 - 这就是我正在使用的解决方案。我在其本身上创建了一个扩展BuildContext
。
extension BuildContextHelper on BuildContext {
AppLocalizations get l {
// if no locale was found, returns a default
return AppLocalizations.of(this) ?? AppLocalizationsEn();
}
}
Run Code Online (Sandbox Code Playgroud)
使用此扩展(并导入它),可以像这样使用它:
context.l.appTitle
Run Code Online (Sandbox Code Playgroud)
或者
context.l.helloUser(name)
Run Code Online (Sandbox Code Playgroud)
恕我直言,它干净且可读,但它不是最短的。
是的,这是需要的。你可以解决这个问题,但这是一个坏主意。
其原因是Localization.of<T>(context, T)
可能会随着时间的推移而更新。它的一些情况是:
如果您没有按照应有的方式正确调用Localization.of
内部构建,那么在这些情况下您的 UI 可能无法正确更新。
Localization
将对象存储在您的内部是完全可以的State
,并且在这种情况下效果非常好。
如果你只想让它看起来更好,你也可以在 build 方法中声明变量:
@override
Widget build(BuildContext context) {
final l = Localization.of(context);
return Text(l.myAppTitle);
}
Run Code Online (Sandbox Code Playgroud)
在 a 中,您还可以使用空感知运算StatefulWidget
符重新分配变量 in或仅分配一次,因为对象不会随时间变化:didChangeDependencies
??=
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);
}
Run Code Online (Sandbox Code Playgroud)
在 中didChangeLocales
,您每次都可以重新分配。这可确保变量始终保留适当的语言环境,并在第一次构建时进行初始化(使用didChangeDependencies
)。请注意,我还包含了一个WidgetsBindingObserver
,您需要按代码中所示处理它。
归档时间: |
|
查看次数: |
5071 次 |
最近记录: |