flutter - 如何等待一个类初始化?

我有一个类,calendar,它异步读取文件。

// Copyright 2017 <Abhi Agarwal>
// Refer to LICENSE

// Dart Imports
import 'dart:async';
import 'dart:convert';

// Flutter Imports
import 'package:flutter/services.dart';

// Local Imports
import 'event.dart';

/// Class deals with the school-wide calendar Calendar.
class Calendar {
  /// The days off in the year.
  List<Event> daysOff = new List<Event>();

  /// The half-days, not necessarily days off.
  List<Event> halfDays = new List<Event>();

  /// Vacations, extended days off.
  List<Event> vactations = new List<Event>();

  DateTime schoolStart;
  DateTime schoolEnd;
  DateTime schoolMaxEnd;

  Calendar() {
    _addDaysOff();
    //  _addHalfDays();
    //  _addVacations();
    //  _addTimes();
  }

  static const String filePath = "assets/calendar/";

  /// Reads a JSON File specified by the Arguments and returns a Decoded Object.
  Future<List<Map<String, String>>> _readJson(String fileName) async =>
      await JSON.decode(await rootBundle.loadString(filePath + fileName));

  Future _addDaysOff() async {
    const String fileName = "days_off.json";
    final List<Map<String, String>> parsed = await _readJson(fileName);

    for (final Map<String, String> item in parsed) {
      Event event = new Event(item["name"], DateTime.parse(item["date"]));
      daysOff.add(event);
    }
  }
}

这一切都很好,但是当我想运行一个简单的测试时就会出现问题。

// Copyright 2017 <Abhi Agarwal>
// Refer to LICENSE

import 'package:flutter/material.dart';

import 'definitions/calendar/calendar.dart';

void main() {
  Calendar myCalendar = new Calendar();
  runApp(new Center(child: new Text(myCalendar.daysOff[0].name)));
}

使用 flutter run,我得到 RangeError (index): Invalid value: Valid value range is empty: 0。这是有道理的,List 只有在初始化时才会有元素。问题是,在加载数据之前,如何在其中放置占位符?

最佳答案

您可以重构您的 Calendar 类,以公开一个 Future,以便在 Calendar 准备好使用时完成:

// Private constructor, use create() to get an instance
Calendar._();

// Future that completes when the new Calendar is ready to use
static Future<Calendar> create() async {
  Calendar calendar = Calendar._();
  await calendar._addDaysOff();
  //    await calendar._addHalfDays();
  //    await calendar._addVacations();
  //    await calendar._addTimes();
  return calendar;
}

然后你可以await Future,例如:

main() async {
  Calendar myCalendar = await Calendar.create();
  runApp(new Center(child: new Text(myCalendar.daysOff[0].name)));
}

您可以等待 Calendar 使用 FutureBuilder 进行初始化如果您希望日历在 Flutter 小部件树的更深处由 StatefulWidget 实例化,而不是将其放在根目录中。

https://stackoverflow.com/questions/44477816/

相关文章:

flutter - 如何从字节数据中读取蓝牙特征并将其转换为适当的值(用于 flutter 的蓝牙)

dart - 如何在 Dart 中通过 async* 传输错误?

android - 如何模拟/ stub Flutter 平台 channel /插件?

firebase - 我应该将图片上传到 Cloud Firestore 还是 Firebase S

dart - Column 内展开的小部件未展开,而是不可见

android - Flutter:使用 Sliver 小部件时如何在滚动时隐藏 BottomApp

dart - 在 SnackBarAction onPressed 上 flutter 小吃吧

generics - 如何从 Dart/Flutter 中的泛型函数调用命名构造函数

flutter - 在 SafeArea 中获取小部件高度的正确方法

dart - 如何在 Dart 中将 Class 对象转换为数据结构 `Map` 或 `List o