Dev*_*ior 2 dart flutter flutter-layout
I've got a SQLite database that I query data from. From such data I create the necessary widgets and store them in a list. Passing the list to ListView.builder I create the items from the list. Everything looks good except when I add new data to the widget list. Nothing shows up if I use insert. If I use add there's no issue. Here's the snippet.
List<MessageItem> _messageItems = <MessageItem>[];
// Reads the data and creates the widgets (all OK here)
// Called when reading the data <<<
_readDBMessages() async {
List<Map> messages = await readMessages(_threadID);
List<MessageItem> holderList = <MessageItem>[];
for (final msg in messages) {
holderList.add(new MessageItem(
msg['message'],
msg['timestamp'],
msg['status'],
_contactData['photo']));
}
_messageItems.clear();
setState(() {
_messages = msges;
_messageItems = holderList;
});
}
// When I use _messageItems.add(new MessageItem()); the item shows as expected but it
// it's located on top of the list. Since my ListView is reverse
// I instead use _messagesInsert(0, new MessageItem()); in doing so
// The list is not updated. Scrolling up/down will than proceed to
// show the item as expected.
// Called when storing the data <<<
_storeNewMessage(String message) {
int timestamp = new DateTime.now().millisecondsSinceEpoch;
storeMessage(_threadID, message, _me, 'sending', timestamp, 'text').then((onValue) {
// _readDBMessages();
setState(() {
_messageItems.add(
new MessageItem(
message, timestamp, 'sending', null
)
);
print('Message inserted ---------------');
});
});
}
// Here's my listView constructor <<<
new Expanded(
child: new ListView.builder(
reverse: true,
padding: const EdgeInsets.all(12.0),
itemCount: (_messageItems == null) ? 0 : _messageItems.length,
itemBuilder: (context, i) => _messageItems[i]
)
),
Run Code Online (Sandbox Code Playgroud)
According to Flutter doctor everything is OK, Thanks for the help ;-)
小智 11
我遇到了类似的问题,我正在使用 StreamBuilder 监听 Floor db 更改,其中 StreamBuilder 正在做出反应,但 ListView 没有更新。尝试了上面的解决方案
child: new ListView.builder(
key: UniqueKey(),
Run Code Online (Sandbox Code Playgroud)
然后 ListView 用新数据进行更新,但有一个问题,在上面的实现中,ListView 被刷新,这对于添加新数据非常有用,但是当我更新数据库中的数据或使用可关闭小部件删除数据时,ListView 是再次刷新并显示第一个元素。
所以我尝试将密钥添加到 itemBuilder 中的每个小部件中,它对我有用
ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: array.length,
itemBuilder: (context, index) {
return ListItemWidget(
dao: dao,
item: array[index],
key: UniqueKey(),
);
},
);
Run Code Online (Sandbox Code Playgroud)
也许您应该将唯一密钥传递给自己MessageItem。当您收到数据时:
new MessageItem(
msg['message'],
msg['timestamp'],
msg['status'],
_contactData['photo'],
key: Key(msg['message']+msg['timestamp'].toString())
)
Run Code Online (Sandbox Code Playgroud)
当您添加新条目时:
_messageItems.add(
new MessageItem(
message, timestamp, 'sending', null, key: Key("${message}${timestamp}")
)
);
Run Code Online (Sandbox Code Playgroud)
在MessageItem构造函数中:
MessageItem(..., {Key key}): super(key: key);
Run Code Online (Sandbox Code Playgroud)
另一种方法是为列表指定一个随机密钥,如下所示:
child: new ListView.builder(
key: new Key(randomString()),
Run Code Online (Sandbox Code Playgroud)
您可以在https://flutter.io/widgets-intro/#keys中阅读有关键的信息,也可以查看Dismissible小部件作为示例
| 归档时间: |
|
| 查看次数: |
2780 次 |
| 最近记录: |