首页 文章

颤动:获取默认上下文?或没有上下文加载资产?

提问于
浏览
2

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

我有一个加载此文件的方法:

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

由于搜索字段中的每次更改都会调用SearchDelegate中的@override xy构建方法,我会一遍又一遍地加载我的文件,这当然不太理想 . 我只想在开头加载一次文件 .

有没有办法获得某种我可以使用的默认上下文,例如在SearchDelegate的构造函数中 . 喜欢在android中(如果我正确记得)?

或者我可以在没有 .of(context) 的情况下加载资产文件吗?

2 回答

  • 0

    由于DefaultAssetBundle基于InheritedWidget,因此您将始终 need 传递上下文 .

    of 只是根据BuildContext查找小部件树,直到找到 DefaultAssetBundle 小部件 . 这意味着如果没有 BuildContext ,则无法检索 DefaultAssetBundle 对象 .

    您需要将 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
      }
    }
    

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

  • 1

    您可以将 BuildContext 作为参数传递给 loadCountryData(BuildContext context) .

相关问题