positioning to the top of a listview after having incremented the size of a line
-
Hi,
I have a technical issue about the ListView component.
If I change the height of the items of a ListView, something wrong about the positioning to the top of the list can be observed.For example, a list of items with a height of 40 pixels.
When we click over one of them, the height of the selected item is increased and the height of item selected before is decreased to 40 pixels
When the height of an item is increased more than the visible height of the listview, then positioning to the top of the list becomes wrong.The problem is the same as we use the function positionViewAtIndex() or a calculation with listview.contentY to move to the top if the list.
The problem can be bypassed by using listview.cacheBuffer.
But I think this solution is not a good way because it uses more memory.has anybody an idea of the problem and how to solve it ?
Thanks for your help
Below, the exemple code
import QtQuick 2.6 import QtQuick.Window 2.2 Window { property int listContentHeight : 0 property int collapsedLineHeight : 40 property int indexSel : -1 property bool withFncPositionView : false visible: true width: 800 height: 600 title: qsTr("ListView Demo") Column { x:370 y:200 Text { text: "1 - Clic on the item 1, it expands and moves to the top of the list : OK" } Text { text: "2 - Clic on the item 2, it expands and moves to the top of the list : OK" } Text { text: "3 - Move to item 7 and clic on it, it expands and moves to the top of the list : OK" } Text { text: "4 - Scroll to item 8 and clic on it, it expands but the top of the list becomes wrong" } Text { text: " " } Text { text: "Problem is the same as we use the function positionViewAtIndex() or a calculation" } Text { text: "with listview.contentY to position the top if the list " } } ListModel { id : dataModel ListElement { selected: false; height: 80 ; color: "red" } ListElement { selected: false; height: 120; color: "green" } ListElement { selected: false; height: 70 ; color: "blue" } ListElement { selected: false; height: 90 ; color: "yellow" } ListElement { selected: false; height: 130; color: "purple" } ListElement { selected: false; height: 100; color: "pink" } ListElement { selected: false; height: 80 ; color: "orange" } ListElement { selected: false; height: 554; color: "brown" } ListElement { selected: false; height: 80 ; color: "red" } ListElement { selected: false; height: 120; color: "green" } ListElement { selected: false; height: 70 ; color: "blue" } ListElement { selected: false; height: 90 ; color: "yellow" } ListElement { selected: false; height: 130; color: "purple" } ListElement { selected: false; height: 100; color: "pink" } ListElement { selected: false; height: 80 ; color: "orange" } ListElement { selected: false; height: 554; color: "brown" } } Rectangle { x: 100 y: 200 width: 200 height: 200 color: "#400000FF" ListView { id : view anchors.fill : parent anchors.leftMargin : 20 anchors.rightMargin: 20 focus : true model : dataModel contentWidth : width // with cacheBuffer contentY and positionViewAtIndex run well, but this solution increases the memory use // cacheBuffer : 900 // this animation doesn't work // Behavior on contentY {NumberAnimation{duration: 200}} // this animation works NumberAnimation { id: moveViewAnimation; target: view; property: "contentY"; duration: 200 } delegate: Rectangle { anchors { left: parent.left; right: parent.right } color : model.color opacity : 0.6 height : model.selected? model.height:collapsedLineHeight Text {anchors.leftMargin:20; text:model.index} MouseArea{ anchors.fill: parent onClicked: { // collapses item previously expanded collapse(index) // expands this item and positions view on it model.selected = !model.selected if(model.selected) { moveViewAtIndex(index) indexSel = index } updateContentHeight() } } } } } function collapse(index) { for(var i=0; i < view.model.count; i++) { var object = view.model.get(i) if( object.selected && i!== index ) { object.selected = false break } } indexSel = -1 } function moveViewAtIndex(indexToGo) { if(indexToGo === -1) return if( withFncPositionView ) { view.positionViewAtIndex(indexToGo, ListView.Beginning) } else { moveViewAnimation.stop() var yNew = view.originY + collapsedLineHeight*indexToGo moveViewAnimation.to = yNew moveViewAnimation.start() } } function updateContentHeight() { listContentHeight = 0 for(var i=0; i < view.model.count; i++) { var object = view.model.get(i) listContentHeight += object.selected? object.height : 40 } } }