How to stop ListView for “jumping” when model is c

2019-04-07 12:54发布

What I need to do: I need to create a chat window using a ListView in QML that stores the chat-messages. I set listView.positionViewAtEnd() in order to follow the last messages. I disable positionViewAtEnd when I scroll upwards such that I can read the past messages without jumping at the end every time I receive a new message.

The problem: After scrolling up, every time I receive a new message it jumps at the beginning of list. To solve that I manage to store the contentY of the list and reset it every time onCountChanged handler is called (see the code below):

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)
    }
}   

The problem is that even though I set the last contentY I had, before the model was changed, the list still jumps a bit (several pixels, not at the end or beginning) and it doesn't jump always. And when I go to the top of the list and print the contentY I get negative values. Theoretically, contentY at the beginning of the list should be 0.

Can somebody tell me what is going wrong? Or maybe suggest another solution to create my message list?

Than you in advance! :)

2条回答
可以哭但决不认输i
2楼-- · 2019-04-07 13:40

One possible solution schould be insert ListView into Flickable and disable interactive flag for 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();
            }
        }
    }
查看更多
对你真心纯属浪费
3楼-- · 2019-04-07 13:47

Why not use onCountChanged slot in order to set the ListView at the end ?

onCountChanged: {
   messagesList.positionViewAtEnd()
}
查看更多
登录 后发表回答