如何将列表视图与迭代器一起使用



我想为时间线构建一个"消息卡"ListView。 消息数据来自具有多个筛选函数的容器类。 我只在示例中显示一个。

编辑:澄清卡托因 我目前使用ListView.builder()使此ListView工作,这取决于能够按索引访问源数据中的元素。

我想更改它,以便元素来自在用户滚动列表视图时按需生成的可迭代对象。

在当前工作解决方案中,提供程序有一个返回列表的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

或者,也许答案在于使用原版ListView,children来自迭代器,但我认为这仍然最终会创建列表中的所有消息。

尽管有这个名字,ListView并不强制要求使用List。只需将List与默认构造函数一起使用,但如果使用ListView.builder则可以使用Iterable生成值。下面是一个示例:

@override
Widget build(BuildContext context) =>
ListView.builder(
itemBuilder: (BuildContext _, int i) => 
MessageCard.fromMessageRec(messageData.filterByChildId(childId).elementAt(i)
);

至于允许的物品数量,ListView.builder的文件指出:

此构造函数适用于具有大型(或 无限个子项,因为仅调用构建器 那些真正可见的孩子。 块引用

最新更新