Flutter应用程序在我尝试更改其状态(更改Locale)时重新启动



我正在开发一款应用程序,在让用户使用它之前,它需要做一些事情,即获取手机的语言,并获取一个包含每天显示的信息的在线文件。

因此,现在我已经完成了整个获取区域语言部分,我认为现在是添加加载动画以在获取信息时显示的最佳时机。我用了一个FutureBuilder,它看起来不错。

不过我确实有个问题。当我更改语言时,它会重新启动整个应用程序(包括加载屏幕和全部(,并重置为原始语言,因为它还执行应用程序初始化部分。

这是代码,非常感谢您的帮助!

const en = Locale('en', 'UK');
const fr = Locale('fr', 'FR');
const ja = Locale('ja', 'JA');
var currentLocale = en;
bool localInit = false;
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
static void setLocale(BuildContext context, Locale newLocale) async {
_MyAppState? state = context.findAncestorStateOfType<_MyAppState>();
state!.changeLanguage(newLocale);
}
}
class _MyAppState extends State<MyApp> {
void changeLanguage(Locale newLocale) {
setState(() {
currentLocale = newLocale;
});
}
//this part is the one I use to fetch the phone's Locale
Future<int> initLoc() async {
Locale res;
String? localeCode;
try {
localeCode = await Devicelocale.currentLocale;
} on PlatformException {
print("Error obtaining current locale");
}
switch (localeCode) {
case 'fr':
res = fr;
break;
case 'ja':
res = ja;
break;
default:
res = en;
}
currentLocale = res;
localInit = true;
await new Future.delayed(new Duration(milliseconds: 1000));
return 1;
}

最后是构建方法:

return FutureBuilder(
future: initLoc(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
),
child: SpinKitRotatingCircle(
color: Colors.blue,
size: 50.0,
),
);
case ConnectionState.done:
if (snapshot.hasError) {
return Text("Error loading locale data: ${snapshot.error}");
} else {
return MaterialApp(
locale: currentLocale,
...

我在一些帮助下找到了答案!

这里的问题是future是在构建方法中定义的。因此,要修复它,需要采取两个步骤:

  1. 在应用程序状态下宣布未来
  2. 通过调用initState中的initLoc函数初始化此新属性

下面是它的样子:

class _MyAppState extends State<MyApp> {
late Future<int> _loc;
void changeLanguage(Locale newLocale) {
setState(() {
currentLocale = newLocale;
});
}
Future<int> initLoc() async {...
}
@override
void initState() {
super.initState();
_loc = initLoc();
}
Widget build(BuildContext context) {
return FutureBuilder(
future: _loc,
builder: (context, snapshot) {
switch (snapshot.connectionState) { ...

就这样!注意,在声明这个新变量时,我需要使用late,因为我知道它将被初始化!

最新更新