Flutter:获取默认上下文?或在没有上下文的情况下加载资产? [英] Flutter: get default context? or load assets without context?

查看:84
本文介绍了Flutter:获取默认上下文?或在没有上下文的情况下加载资产?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在扩展SearchDelegate的类中加载json文件以搜索其内容.

I'm trying to load a json file in a class extending SearchDelegate to search through its content.

我有一种加载该文件的方法:

I have a method to load this file:

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等)中可用,而没有外部条件(例如在构造函数中).

Unfortunately this requires a Buildcontext (context) that seems only to be available in the SearchDelegate build methods (like buildActions, buildLeadings, etc), but no outside like for example in the constructor.

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

由于SearchDelegate中的@override xy构建方法随着搜索字段中的每一次更改而被调用,因此我会一遍又一遍地加载我的文件,这当然是不理想的.我只想在开始时加载一次文件.

As the @override xy build methods in SearchDelegate are called with every change in the search field, I would load my file over and over again, which is of course not ideal. I want to load my file once at the beginning only.

有没有一种方法可以获取某种默认上下文,例如可以在SearchDelegate的构造函数中使用的默认上下文.像在android中一样(如果我正确记住的话)?

Is there a way to get some sort of get default context that I could use for example in the constructor of SearchDelegate. Like in android (if I remmeber correctly)?

还是可以在没有 .of(context)的情况下加载资产文件?

Or can I load an assets file without .of(context)?

推荐答案

DefaultAssetBundle 基于 InheritedWidget ,您将始终需要 传递上下文.

of 仅基于

of just looks up the widget tree based on a BuildContext until it finds a DefaultAssetBundle widget. This means that you cannot retrieve a DefaultAssetBundle object without a BuildContext.

您将需要 BuildContext 传递给您的方法.我可以想象像这样的情况:

You will need to pass a BuildContext to your method. I could imagine a situation like the following:

@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
  }
}

如您所见,我从 build 方法传递了 BuildContext . FutureBuilder 也允许处理数据直接在构建树中.

As you can see I passed the BuildContext from the build method. The FutureBuilder also allows to process the data in the build tree directly.

这篇关于Flutter:获取默认上下文?或在没有上下文的情况下加载资产?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆