你有两个问题要解决:
- 如何存储已查看消息的信息
- 何时将其设置为已读。
就这样一个接一个……
delegate 中的自定义属性 不是一个好主意,因为一旦delegate 离开ListView 的视口并被销毁,其中存储的信息就会丢失。
最好的解决方案是将其存储在ListView 的模型中。这样,如果 model 有点持久化,则该信息也可能在应用程序重新启动后仍然存在。
也许您可能会通过我将介绍的下一个选项与@987654327@ 结合来实现一些目标,但我会认为这是骇人听闻的。
如果这是不可能的,并且信息不需要在应用重新启动后仍然存在,那么您需要考虑一种将其存储在 ListView 之外的方法。例如,您可以使用array 或object/dictionary 来存储它(注意:没有更改通知)。您还可以使用第二个 ListView 保持同步(这可能证明并不容易!)。
最后,您可以将 ListView 作为模型放入 Instantiator 中,它使用一个属性实例化简单的 QtObjects:读取。
后者是将其存储在代表和模型之外的最简单方法,因此我将向您展示它是如何工作的:
Instantiator {
id: additionalInfo
model: customModel
delegate: QtObject {
property bool read // <--- This is a custom defined property
}
}
ListView {
model: customModel
delegate: MyDelegate {
onRead: additionalInfo.objectAt(index).read = true
Text {
text: additionalInfo.objectAt(index).read ? 'read' : 'unread'
}
}
}
现在是第二部分:什么时候真正阅读
您已经发现的可见性问题。 Items 在为 buffer 创建时,即使在 listView 之外也可见。所以你不能使用这些信息。但是你有以下信息:
-
listModel.contentItem 的位置(x 和 y)
-
delegate 相对于listModel.contentItem 的位置
-
delegate 的宽度和高度
所以你可以说:delegate 是完全可见的,如果:
listModel.contentItem.x + delegate.x >= 0
listModel.contentItem.y + delegate.y >= 0
listModel.contentItem.y + delegate.y + delegate.height <= listModel.height
listModel.contentItem.x + delegate.x + delegate.width <= listModel.width
一个例子,关于Item如何检查它是否在Flickable中可见(记住:ListViewISFlickable)可以找到here
这是:如果有可能让整个委托都拥有视图。如果它更大 - 那么您需要在委托被视为已读取时定义一些标准。
但同样:如果有任何可能将其作为您的model 中的角色,请将其放在那里!