【发布时间】:2021-12-02 14:50:41
【问题描述】:
当我尝试通过ListView 显示数据时,每次更新模型时,视图都会返回到开头。
有没有办法让ListView 处理模型更新而不更改内部Flickable 的visibleArea(或以合理的方式更改它)?
理想情况下,同一区域应保持可见。
这是一个您可以看到该行为的最小示例:如果您在flickable(左侧)和listView(右侧)中向下滚动,当计时器被触发时,第一个计时器将停留在您所在的位置离开它,第二个会回到开头。
QML online live example
import QtQuick 2.15
Rectangle {
id:root
property int model: 10
property int delegateHeight: height/10*0.8
property int delegateSpacing: height/10*0.2
color: "#afafaf"
anchors.fill: parent
Timer {
interval: 5000
repeat: true
running: true
onTriggered: root.model++
}
Flickable {
id: flickable
x: 0
y: 0
width: parent.width/2
height: parent.height
clip: true
contentHeight: root.delegateHeight*repeater.count
Repeater {
id: repeater
model: root.model
delegate: Rectangle {
x: 0
y: (root.delegateHeight+root.delegateSpacing)*index
width: flickable.width
height: root.delegateHeight
color: "#abcdef"
Text {
text: index+1
}
}
}
}
ListView {
id: listView
x: parent.width/2
y: 0
width: parent.width/2
height: parent.height
clip: true
model: root.model
spacing: root.delegateSpacing
delegate: Rectangle {
width: ListView.view.width
height: root.delegateHeight
color: "#fedcba"
Text {
text: index+1
}
}
}
}
编辑:我找到了一种解决方法,但我认为这不是正确的方法。
像这样添加到listView 会保持visibleArea 在模型上的位置增加,但在减少计数器时可能会有一些缺点。
property real lastY: 0
onContentYChanged: {
if(!moving){
listView.contentY = listView.lastY+listView.originY
}
listView.lastY = listView.contentY-listView.originY
}
【问题讨论】:
-
您为什么不认为您的解决方法是正确的方法?
-
我认为,如果在视图显示内容区域的底部时,内容会缩小,就像在上面的示例中降低模型数量一样,它可能会出现异常。可能我在计算新内容位置时必须考虑内容的大小。明天我会尝试证明我的观点。
-
您可能需要为这种情况做一些额外的事情,但我根本不认为这是一种解决方法。我认为这可能是实现您想要的唯一方法。当模型发生变化时,ListView 不知道你想看到新数据的哪一部分,所以你必须手动滚动它,这似乎是你在做的事情。