因此,我有一个屏幕,其中显示文本和文本上方的图像,并在后台从共享首选项中加载一些数据。
但是图像要花很长时间才能加载,并且当我删除获取共享首选项数据的调用时,图像加载非常不稳定。有人知道我在给这个电话做错什么吗?
代码如下:
class WelcomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
precacheImage(AssetImage(Images.tomato), context);
_loadData(context);
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
Strings.appName,
style: TextStyle(
color: AppColors.black,
fontSize: 50.0,
fontWeight: FontWeight.w600,
),
),
Image.asset(Images.tomato),
],
),
),
);
}
void _loadData(BuildContext context) async {
final PreferencesRepository repository = PreferenceRepositoryImp();
repository.loadAll().then(
(_) {
sleep(Duration(seconds: 2));
Navigator.pushNamedAndRemoveUntil(context, Routes.HOME, (_) => false);
},
);
}
}
这就是图片
答案 0 :(得分:2)
您正在使用sleep(Duration(seconds: 2));
来暂停所有内容。您不应该使用sleep
,尤其是在build
方法内部。 Dart是单线程的,这意味着当它停止线程时,它将阻止构建UI。
此外,如果您不使用_loadData
关键字,为什么async
被标记为await
?仅在要使用await
关键字时才需要它,否则将其删除。如果要使用它,则应使用await Future.delayed(Duration(seconds: 2))
使其等待。在这里:
void _loadData(BuildContext context) async {
final PreferencesRepository repository = PreferenceRepositoryImp();
await repository.loadAll();
await Future.delayed(Duration(seconds: 2));
Navigator.pushNamedAndRemoveUntil(context, Routes.HOME, (_) => false);
}
await
与sleep
有何区别? await
让Dart说:“嘿,将来我会继续注意这一点”(哈哈明白了吗?未来?哈哈哈哈哈,我很有趣)。无论如何,它不会继续执行_loadData
函数,因为它想要该值,但是它将继续运行(在您的示例中)build方法,然后当Future
返回一个值时,它将是就像“嘿!我一直在寻找那个值!现在我可以继续运行该功能!”
sleep
使Dart说“我将在获得的时间内小睡”(在本例中为两秒钟)。由于Dart是单线程的,因此它在“唤醒”之前不会做任何事情。在经过两秒钟的小睡之后,它将继续执行该功能,并在完成后继续执行build方法,因此,将加载您的映像,这说明了为什么需要这么长时间。