ListView.onRemove 动画 vs childrenRect.height
ListView.onRemove animation vs childrenRect.height
当我使用 ListView.onRemove 动画从其模型中删除元素时,我注意到 ListView childrenRect.height 中有奇怪的行为。当我删除除最后一个元素之外的所有元素时,childrenRect.height 属性 是错误的,但是 contentHeight 属性 是可以的。删除 ListView.onRemove 动画结果问题消失了。为什么 childrenRect.height 是错误的?
使用this code你会发现在你移除除最后一个元素之外的所有元素后,你无法在某些区域点击。
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 }
}
}
}
}
因为ListView.childrenRect
可能会自己动态改变。例如,尝试在示例代码启动时拖动视图。当所有四个代表从视图顶部消失时,childrenRect.height
增加(即使您注释掉 NumberAnimation
)。
这意味着 ListView
将它的 childrenRect
用于内部的某些东西,比如拖动动画,因此这个 属性 对 ListView 用户来说是不可靠的。
使用 contentHeight
而不是 childrenRect.height
,这样您总能获得正确的值。或者使用 contentItem.childrenRect.height
根据 Flickable.
做同样的事情
当我使用 ListView.onRemove 动画从其模型中删除元素时,我注意到 ListView childrenRect.height 中有奇怪的行为。当我删除除最后一个元素之外的所有元素时,childrenRect.height 属性 是错误的,但是 contentHeight 属性 是可以的。删除 ListView.onRemove 动画结果问题消失了。为什么 childrenRect.height 是错误的?
使用this code你会发现在你移除除最后一个元素之外的所有元素后,你无法在某些区域点击。
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 }
}
}
}
}
因为ListView.childrenRect
可能会自己动态改变。例如,尝试在示例代码启动时拖动视图。当所有四个代表从视图顶部消失时,childrenRect.height
增加(即使您注释掉 NumberAnimation
)。
这意味着 ListView
将它的 childrenRect
用于内部的某些东西,比如拖动动画,因此这个 属性 对 ListView 用户来说是不可靠的。
使用 contentHeight
而不是 childrenRect.height
,这样您总能获得正确的值。或者使用 contentItem.childrenRect.height
根据 Flickable.