Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
6.7.2
-
None
Description
When the delegate of a ListView is a Layout (e.g. Column, Row, ...) and the ListView has move/displaced animations, it will incorrectly position the elements of the ListView when the size of the delegate changes.
The screenshot below illustrates the issue. The right ListView's delegate is just a Rectangle with Text. The left ListView's has the same delegate but wrapped in a Column. The width and height are explicitly set on the Rectangle, so the ListViews should look identical. However, when triggering an animation (with the shuffle button), their positions will diverge.
Sample QML code:
import QtQuick import QtQuick.Controls Window { id: window width: 640 height: 480 visible: true title: qsTr("Animation bug") property list<real> heights: [16, 32, 48, 64, 80] ListModel { id: list ListElement { text: "A" } ListElement { text: "B" } ListElement { text: "C" } ListElement { text: "D" } ListElement { text: "E" } } component Delegate: Rectangle { id: delegate; required property string text required property int index width: 32 height: window.heights[delegate.index]; color: "red"; Text { anchors.verticalCenter: parent.verticalCenter text: delegate.text } } component List : ListView { model: list width: 32 spacing: 8 anchors { top: parent.top bottom: parent.bottom } displaced: Transition { NumberAnimation { properties: "y" easing.type: Easing.InOutQuad; duration: 200 } } move: Transition { NumberAnimation { properties: "y" easing.type: Easing.InOutQuad; duration: 200 } } } List { id: columnListView delegate: Column { id: columnDelegate required property int index required property string text width: 32 Delegate { index: columnDelegate.index text: columnDelegate.text } } } List { id: listView anchors { left: columnListView.right leftMargin: 16 } delegate: Delegate {} } Button { id: button anchors.right: parent.right anchors.top: parent.top anchors.margins: 8 text: "Shuffle" function shuffleItems() { for(let i = 0; i < window.heights.length - 2; ++i) { let j = i + Math.floor(Math.random() * (window.heights.length - i)); list.move(i, j, 1); } } onPressed: shuffleItems(); } }