I noticed strange behaviour in ListView childrenRect.height when I am removing elements from its model with ListView.onRemove animation. When I remove all elements except the last one, childrenRect.height property is wrong, but contentHeight property is ok. Removing ListView.onRemove animation results the problem disappears. Why childrenRect.height is wrong?
Using this code You will see that after You remove all elements except the last one, You cannot click in some area.
import QtQuick 2.0
import QtQuick.Controls 1.0
MouseArea
{
id: container
height: 400; width: 600
Rectangle { id: point; visible: false; width: 6; height: 6; radius: 3; color: "black" }
onPressed: { point.visible = true; point.x = mouse.x - 3; point.y = mouse.y - 3; }
ListModel {
id: listModel
ListElement { lorem: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Proin nibh augue, suscipit a, scelerisque sed, lacinia in, mi. Cras vel lorem." }
ListElement { lorem: "Etiam pellentesque aliquet tellus. Phasellus pharetra nulla ac diam." }
ListElement { lorem: "Quisque semper justo at risus. Donec venenatis, turpis vel hendrerit interdum, dui ligula ultricies purus, sed posuere libero dui id orci." }
ListElement { lorem: "Nam congue, pede vitae dapibus aliquet, elit magna vulputate arcu, vel tempus metus leo non est." }
}
ListView {
id: messageListView
model: listModel
anchors.top: container.top; anchors.left: container.left; anchors.right: container.right
height: childrenRect.height
onCountChanged: console.log("count: " + count)
onHeightChanged: console.log("height: " + height) // sometimes wrong
onContentHeightChanged: console.log("contentHeight: " + contentHeight) // rather ok
delegate: Item {
id: messageItem
anchors.left: parent.left; anchors.right: parent.right
height: Math.max(50, messageText.height + 12)
Rectangle { anchors.fill: parent; anchors.margins: 1; opacity: 0.75; color: "green"; radius: 5 }
Text {
id: messageText
anchors.verticalCenter: parent.verticalCenter; anchors.left: parent.left; anchors.right: removeButton.left; anchors.margins: 10
text: lorem
color: "white"; horizontalAlignment: Text.AlignHCenter; wrapMode: Text.WordWrap
font.pixelSize: 16; font.weight: Font.Bold
style: Text.Outline; styleColor: "black"
maximumLineCount: 6; elide: Text.ElideRight
}
Button {
id: removeButton
enabled: (index !== -1) && (messageItem.opacity === 1.0)
anchors.right: parent.right; anchors.margins: 5
anchors.verticalCenter: parent.verticalCenter; implicitHeight: 40; implicitWidth: 40
onClicked: {
console.log("remove: " + index);
listModel.remove(index);
}
}
ListView.onRemove: SequentialAnimation {
PropertyAction { target: messageItem; property: "ListView.delayRemove"; value: true }
/// PROBLEM BEGIN
NumberAnimation { target: messageItem; properties: "opacity"; from: 1.0; to: 0.0; duration: 500 }
/// PROBLEM END
PropertyAction { target: messageItem; property: "ListView.delayRemove"; value: false }
}
}
}
}
Because the ListView.childrenRect
may be dynamically changed by itself. For example, try to drag the view when your example code launched. As all four delegates disappeared from the top of the view, childrenRect.height
increased (even if you comment out the NumberAnimation
).
That means ListView
uses it's childrenRect
to something internally, like drag animation, thus this property is not reliable to ListView users.
Use contentHeight
instead of childrenRect.height
so you can always obtain the correct value . Or use contentItem.childrenRect.height
that does the same thing according to Flickable.