如何停止ListView for" jump"当模型改变时

时间:2015-06-25 07:22:23

标签: qt listview model qml qtquick2

我需要做什么:我需要使用存储聊天消息的QML中的ListView创建聊天窗口。我设置了listView.positionViewAtEnd()以便跟踪上一条消息。当我向上滚动时,我禁用positionViewAtEnd,这样我每次收到新消息时都可以读取过去的消息而不会跳到最后。

问题:向上滚动后,每当我收到新消息时,它会在列表的开头跳转。要解决此问题,我设法存储列表的contentY并在每次调用onCountChanged处理程序时重置(请参阅下面的代码):

ListView {
    id: messagesList
    model: contact? contact.messages: []
    delegate: delegate
    anchors.fill: parent
    anchors.bottomMargin: 20
    height: parent.height
    anchors.margins: 10

    property int currentContentY

    onMovementEnded: {
       currentContentY = contentY
    }

    onCountChanged: {
        contentY = currentContentY
    }
    onContentYChanged: {
        console.log(".....contentY: " + contentY)
    }
}   

问题在于,即使我设置了最后一个contentY,在模型更改之前,列表仍然会跳跃几个像素 ,而不是在结束或开始)和它不会总是。当我转到列表顶部并打印 contentY时,我会得到负值。从理论上讲,列表开头的contentY应为0

有人可以告诉我出了什么问题吗?或者可能建议另一种解决方案来创建我的消息列表

比你提前! :)

2 个答案:

答案 0 :(得分:1)

为什么不使用onCountChanged插槽来设置ListView?

onCountChanged: {
   messagesList.positionViewAtEnd()
}

答案 1 :(得分:1)

一种可能的解决方案是将ListView插入Flickable并禁用ListView的交互式标志

    Flickable {
        id: fparent
        anchors.fill: parent
        anchors.bottomMargin: 20
        anchors.margins: 10

        interactive: true
        clip: true
        flickableDirection: Flickable.VerticalFlick
        contentHeight: messagesList.height

        ListView {
            id: messagesList
            width: parent.width
            height: childrenRect.height
            clip: true
            model: contact? contact.messages: []
            delegate: delegate
            interactive: false
            onCountChanged: {
                fparents.returnToBounds();
            }
        }
    }