在 QML 开发中 Listview 是经常用的控件,作用过程中发现一个 bug 当每个 delegate 的高度不等的时候,在上下滑动过程中会引起contentY 的变动, 上下来加多滑动几次,加到顶部后 contentY 不再是原来的值了(默认为 0),这时候如果要通过 contentY 做类似下拉刷新的效果就会出问题了。Qt 官方 bug list 说暂时不处理了 https://bugreports.qt.io/browse/QTBUG-31573
经过大量测试,发现 originY 也会随着 contentY 的变化面变化, 最后确认做类似下拉刷新的效果时所有用到 contentY 的地方都用 (contentY - originY)替换就可以了,在Qt 提供的example// qtdeclarative/examples/quick/demos/tweetsearch, 验证过,确实可行,是一种解决办法,现将验证部分代码粘贴如下,提供给各位同学参考,希望同学们斧正:
// qrc:/demos/tweetsearch/tweetsearch.qml // part code
ListView {
id: mainListView
anchors.fill: parent
// delegate: TweetDelegate { }
// model: ListModel { id: finalModel }
model: 200 // for test
delegate: Item { // for test
width: parent.width
height: 40 + Math.random() * 100 // for varying height items
Rectangle {
width: parent.width
height: 1
color: "#999"
anchors.bottom: parent.bottom
}
Text {
anchors.centerIn: parent
text: qsTr("text item %1").arg(index)
}
}
add: Transition {
NumberAnimation { property: "hm"; from: 0; to: 1.0; duration: 300; easing.type: Easing.OutQuad }
PropertyAction { property: "appear"; value: 250 }
}
onDragEnded: if (header.refresh) { tweetsModel.reload() }
ListHeader {
id: header
// y: -mainListView.contentY - height
// here use (contentY - originY) replace contentY
y:(-(mainListView.contentY - mainListView.originY)) - height
}
//qrc:/demos/tweetsearch/content/ListHeader.qml // part code
states: [
State {
//name: "base"; when: mainListView.contentY >= -120
// here use (contentY - originY) replace contentY
name: "base"; when: (mainListView.contentY - mainListView.originY) >= -120
PropertyChanges { target: arrow; rotation: 180 }
},
State {
// name: "pulled"; when: mainListView.contentY < -120
// here use (contentY - originY) replace contentY
name: "pulled"; when: (mainListView.contentY - mainListView.originY) < -120
PropertyChanges { target: label; text: "Release to refresh..." }
PropertyChanges { target: arrow; rotation: 0 }
}
]