下面是提供程序类的代码。每当应用启动时,我都想获取保存在共享首选项中的表格。但是,从共享首选项加载需要花费一些时间。因此,当我第一次访问表单时,它最初是空的,我得到一个空列表。无论如何,有没有延迟吸气剂直到它具有表单模型的对象。
class FormProvider with ChangeNotifier {
FormProvider() {
loadformPreferences();
}
List<FormModel> _forms = [];
List<FormModel> get forms => _forms;
Future<void> saveForm(FormModel form) async {
_forms.add(form);
await saveformPreferences();
notifyListeners();
}
Future<void> saveformPreferences() async {
List<String> myforms = _forms.map((f) => json.encode(f.toJson())).toList();
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setStringList('forms', myforms);
}
Future<void> loadformPreferences() async {
// WidgetsFlutterBinding.ensureInitialized();
SharedPreferences prefs = await SharedPreferences.getInstance();
var result = prefs.getStringList('forms');
if (result != null) {
_forms = result.map((f) => FormModel.fromJson(json.decode(f))).toList();
}
}
}
答案 0 :(得分:1)
在Flutter中,与构建UI相关的所有操作都不得异步(或昂贵),以保持较高的帧速率。
因此,即使您假设可以找到一种方法来“等待” SharedPreferences的结果,这也是不希望的,因为所做的任何等待都会阻止UI的进展。
因此,有两种方法可以解决这个常见问题:
最简单的解决方案是通过在Provider
中表示某种初始状态来显式处理Provider
尚未获取其数据的情况。一种简单的方法是将_forms
初始化为null
而不是[]
。然后,在您的Widget.build
方法中,当结果为null
时,您可以执行一些特定的操作(例如显示加载微调器):
Widget build(BuildContext context) {
final provider = Provider.of<FormProvider>(context);
if (provider.forms == null) {
return CircularProgressIndicator();
}
// Otherwise, Do something useful with provider.forms
}
假设您在用户执行某个操作(例如单击按钮)之前,不使用FormProvider
。此时,您使用FormProvider
将新视图推入导航器。
如果您希望保证FormProvider
总是用SharedPreferences
值初始化,则可以将新视图的构造延迟到SharedPreferences
完成:
class MyButton extends StatelessWidget {
Widget build(BuildContext context) {
return Button(onClick: () async {
final forms = await _fetchFormsFromSharedPrefs();
Navigator.push(context, MaterialPageView(builder: (context) =>
Provider(create: (_) => FormProvider(forms))));
});
}
}