Флаттер: получить контекст по умолчанию? или загрузить активы без контекста? - PullRequest
0 голосов
/ 30 июня 2018

Я пытаюсь загрузить файл json в класс, расширяющий SearchDelegate, для поиска по его содержимому.

У меня есть способ загрузить этот файл:

Future<void> loadCountryData() async {
    try {
      String data = await DefaultAssetBundle
          .of(context)
          .loadString("assets/data/countries.json");
      _countries = json.decode(data);
    } catch (e) {
      print(e);
    }
}

К сожалению, для этого требуется Buildcontext (контекст), который, по-видимому, доступен только в методах сборки SearchDelegate (например, buildActions, buildLeadings и т. Д.), Но не снаружи, как, например, в конструкторе.

https://docs.flutter.io/flutter/material/SearchDelegate-class.html

Поскольку методы сборки @override xy в SearchDelegate вызываются при каждом изменении в поле поиска, я загружаю свой файл снова и снова, что, конечно, не идеально. Я хочу загрузить свой файл только один раз в начале.

Есть ли способ получить некоторый контекст получения по умолчанию, который я мог бы использовать, например, в конструкторе SearchDelegate. Как в андроиде (если я правильно помню)?

Или я могу загрузить файл ресурсов без .of(context)?

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Поскольку DefaultAssetBundle основано на InheritedWidget, вам всегда нужно до передать контекст .

of просто ищет дерево виджетов на основе BuildContext, пока не найдет виджет DefaultAssetBundle. Это означает, что вы не можете получить объект DefaultAssetBundle без BuildContext.

Вам понадобится , чтобы передать BuildContext вашему методу. Я мог представить себе ситуацию, подобную следующей:

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: loadCountryData(context: context),
    builder: (BuildContext context, AsyncSnapshot<JSON> jsonData) {
      if (!jsonData.hasData) {
        return Text('not loaded');
      }
      return Text('loaded'); // here you want to process your data
    },
  );
}

/// I am not sure what your decode returns, so I just called it JSON
/// I thought it would make more sense to return the JSON to use it in build
Future<JSON> loadCountryData({BuildContext context}) async {
  try {
    String data = await DefaultAssetBundle
      .of(context)
      .loadString("assets/data/countries.json");
    return json.decode(data);
  } catch(e) {
    print(e);
    return JSON.empty(); // imagine this exists
  }
}

Как видите, я передал BuildContext от build метода. FutureBuilder также позволяет напрямую обрабатывать данные в дереве сборки.

0 голосов
/ 30 июня 2018

Вы можете задать BuildContext в качестве параметра до loadCountryData(BuildContext context).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...