获取列表视图委托qml的可见性状态

e.j*_*dar 3 qml

我正在开发聊天系统,我有一个对话页面,里面有一个列表视图,列表视图代表是文本对话。我想将可见/未见或已读/未读添加到对话委托,由自定义模型提供的列表视图,我需要类似委托附加属性的东西,该属性在实际查看委托时会发生变化。是否有任何附加属性可以告诉我每个委托项目的可见性状态?

der*_*erM 5

你有两个问题需要解决:

  1. 如何存储消息已被查看的信息
  2. 何时将其设置为已读。

于是,一个又一个……

中的自定义属性并不是一个好主意,因为一旦离开视图的视口并被破坏,delegate其中存储的信息就会丢失。delegateListView

最好的解决方案是将其存储在 的ListView模型中。这样,如果信息model有些持久,该信息也有可能在应用程序重新启动后仍然存在。
也许你可以通过我将介绍的下一个选项来实现一些目标,Settings但我认为这很黑客。

如果这是不可能的,并且信息不需要在应用程序重新启动后继续存在,那么您需要考虑一种将其存储在ListView. 例如,您可以使用arrayobject/dictionary来存储它(注意:没有更改通知)。ListView您也可以使用保持同步的第二个(这可能并不那么容易!)。

最后,您可以将您的ListView模型作为模型放入Instantiator,该模型QtObjects使用一个属性简单地实例化:read。

后者是将其存储在委托和模型之外的最简单方法,所以我将向您展示它是如何工作的:

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'
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在是第二部分:什么时候真正阅读

您已经发现了可见性的问题。当它们为 . 创建时,Item即使在 . 外部也可见。所以您不能使用此信息。但你有以下信息:listViewbuffer

  • 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有关 a如何检查 a 是否在 a 中可见Flickable(记住: aListView a )的示例可以在此处Flickable找到

这是:是否可以让整个委托拥有视图。如果它更大 - 那么您需要在委托被视为已读时定义一些标准。

但再次强调:如果有可能将其作为您的角色中的一个角色model,请将其放在那里!