flutter - 如何使用带有迭代器的 ListView
问题描述
我想ListView
为时间线制作一张“留言卡”。消息数据来自具有多个过滤功能的 Container 类。我在示例中只展示了一个。
编辑:CLARIFICATOIN 我目前有这个 ListView 使用 ListView.builder() 工作,这取决于能够通过索引访问源数据中的元素。
我想更改它,以便元素来自一个迭代,该迭代是在用户滚动列表视图时按需生成的。
在当前的工作解决方案中,提供者有一个 findByChildId,它返回一个列表。该列表通常很长,用户可能只想查看最后 100 条左右的消息。
因此,为了不扫描数千条消息以返回数千条消息,我想象使用 findByChildId 会在用户滚动时产生项目。
class MessageData with ChangeNotifier {
List<MessageRec> _messages;
// New Iterable to lazily search only for items the user wants to look at
Iterable<MessageRec> filterByChildId({String childId}) sync* {
if (childId == null) {
throw 'insanity check - Cannot search for null Child ID';
}
String previous;
if (_messages != null) {
for (MessageRec r in _messages) {
if (r.properties['thread'] == childId) {
if (previous == null || ymdFromDt(r.timeSent) != previous) {
yield DateMark.fromDateString(previous); // Special Message inserted
previous = ymdFromDt(r.timeSent);
}
yield r;
}
}
}
}
// And many other supporting methods here.
}
Note: I assume the above works - this is my first forray into Iterables in Dart / flutter.
The above used to be a method that returned a list of MessageRec by iterating over the entire list and returning all matching items.
The ListView.builder could get items from the resulting list because the elements of a List can be accessed by index.
```dart
... Timeline Widget ...
@override
Widget build(BuildContext context) {
return Consumer<MessageData>(
builder: (context, messageData, _) {
return ListView.builder((context, itemIndex) {
// How to access elements from messageData.filterByChildId(childId) here
MessageRec nextMessage = messageData.filterByChildId(childId)[itemIndex];
// The above does not work because there is no indexing on Iterables
return MessageCard.fromMessageRec(nextmessage);
}
);
}
);
}
... snip rest of Widget methods
或者答案可能在于使用带有children
迭代器形式的普通 ListView,但我认为这仍然会最终创建列表中的所有消息。
解决方案
尽管有名称,ListView
但并不强制使用List
. 您只需将 aList
与默认构造函数一起使用,但如果使用ListView.builder
,您可以使用 anIterable
来生成值。这是一个例子:
@override
Widget build(BuildContext context) =>
ListView.builder(
itemBuilder: (BuildContext _, int i) =>
MessageCard.fromMessageRec(messageData.filterByChildId(childId).elementAt(i)
);
至于允许的项目数量,文件ListView.builder
指出:
此构造函数适用于具有大量(或无限)子级的列表视图,因为仅对那些实际可见的子级调用构建器。块引用
推荐阅读
- typescript - 如何将字符串联合重新映射为数字联合?
- python - 自动化导入模块
- c++ - C++20协程,co_return后调用者函数未完成(看起来像挂起)
- function - 如何在循环中将 lines() 迭代器作为参数传递给函数
- javascript - 如何将查询参数传递给重新连接的 websocket?
- python - 在python中打印输出的开头添加空格
- node.js - Lambda 流编码字符串
- tensorflow - 如何将数据集拆分为张量流中的输入和标签?
- node.js - 来自下一个 js 应用程序的 Graphql 400 错误请求?
- go - 在不同长度的字符串上将字符串编码为其 ASCII 表示