How to stop ListView to "jump" when changing a model

What do I need to do . I need to create a chat window using ListView in QML, where chat messages are stored. I set listView.positionViewAtEnd() to keep track of the latest posts. I will turn off positionViewAtEnd when I scroll up so I can read past messages without skipping at the end every time I get a new message.

Problem . After scrolling every time I receive a new message, it jumps to the top of the list. To decide that I manage to store contentY in a list and reset every time the onCountChanged handler is called (see 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 if I set the last contentY that I had, before changing the model the list still skips a bit (a few pixels , not at the end or the beginning) and it does not always jump . And when I go to the top of the list and print contentY , I get negative values . Theoretically, contentY at the top of the list should be 0 .

Can someone tell me what is going wrong? Or maybe suggest another solution to create a list of my posts?

Than you in advance! :)

+6
source share
2 answers

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

 onCountChanged: { messagesList.positionViewAtEnd() } 
+1
source

One possible solution would be to insert a ListView into Flickable and disable the 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(); } } } 
+1
source

Source: https://habr.com/ru/post/989718/


All Articles