如何在颤抖中等待吸气剂?

时间:2020-07-08 04:28:56

标签: flutter dart flutter-provider

下面是提供程序类的代码。每当应用启动时,我都想获取保存在共享首选项中的表格。但是,从共享首选项加载需要花费一些时间。因此,当我第一次访问表单时,它最初是空的,我得到一个空列表。无论如何,有没有延迟吸气剂直到它具有表单模型的对象。

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();
    }
  }
}

1 个答案:

答案 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))));
    });
  }
}