访问AsyncSnapshot中的嵌套属性



所以,我正在学习使用Flutter中的FutureBuilder类。我的代码可以工作,但我想知道我是否可以改进从快照访问数据的方式。我的FutureBuilder是这样的:

@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: FutureBuilder<List<ListCard>>(
future: items,
builder: (context, snapshot) {
return RefreshIndicator(
onRefresh: _pullRefresh,
child: _listView(snapshot),
);
},
),
),
);
}

itemsFuture<List<ListCard>>型的一类性质。_listView是我在快照上工作的方法。这段代码中有两个错误:

Widget _listView(AsyncSnapshot<List<ListCard>> snapshot) {
if (snapshot.data != null) {
return ListView.builder(
itemCount: snapshot.data.length, // Error when accessing the length property
itemBuilder: (context, index) {
return snapshot.data[index]; // Error when accessing the index
},
);
} else {
return const Center(child: CircularProgressIndicator());
}
}

这两个错误实际上是相同的。他们说:

属性'length'不能无条件访问,因为接收者可以是'null'。尝试使访问有条件(使用'?.')或者向目标添加空检查("!").dart (unchecked_use_of_nullable_value)

我知道snapshot.dataList<ListCard>?类型的,因此它的值可以是nullList<ListCard>类型的列表。如果该值为空,Flutter将显示CircularProcessIndicator。如果它不为空,那么将返回ListView.builder小部件。如果我们到达这个点,snapshot.data总是一个列表(它已经在If语句中测试过了),因此它应该有一个长度属性。

我也试过:

Widget _listView(AsyncSnapshot<List<ListCard>> snapshot) {
if (snapshot.data is List<ListCard>) {
//...
}

,但它给出完全相同的错误。

Widget _listView(AsyncSnapshot<List<ListCard>> snapshot) {
if (snapshot.hasData) {
//...
}

但是,我可以通过添加!操作符来消除这些错误:

//...
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return snapshot.data![index];
},
//...

我也可以做一个类型断言,如List<ListCard> data = snapshot.data as List<ListCard>;,但我不想那样做。

不使用!操作符是否可以使此工作?

谢谢!

我认为你面临的问题是因为snapshot不能被提升为非空。

在您的情况下,您将不得不使用">!

"; 记得

类型提升只适用于局部变量…促进实例变量是不可靠的,因为它可能被Getter,它运行一个计算并分别返回一个不同的对象调用它的时间。参考dart-lang/language#1188进行讨论一种类似于类型提升但基于动态的机制检查,并链接到相关讨论

有关此主题的进一步信息,请参阅此回答。

你处理builder的方式是错误的,试试这个:

builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<ListCard> data = snapshot.data ?? [];
return RefreshIndicator(
onRefresh: _pullRefresh,
child: _listView(data),
);
}
}
},

这里我设置data的默认值,如果它为空,我将传递空列表。

相关内容

  • 没有找到相关文章

最新更新