Flutter:获取默认上下文?或在没有上下文的情况下加载资产? [英] Flutter: get default context? or load assets without context?
问题描述
我正在尝试在扩展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
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屋!