如何实现更好的ListView缓存控制?

时间:2018-09-04 20:20:44

标签: qt qml

我尝试使用cacheBuffer,但是当我想完全禁用缓存时,这只会帮助我增加缓存的委托的数量。

现在具有零缓存缓冲区的示例(仅在所有ListView上扩展了一项)的行为如下:

  • 首先,ListView创建两个委托:当前可见和 下一个。
  • 当我向前滚动列表时,它会创建并保留最多4个代表,而不会开始销毁它们。
  • 当我开始向后滚动列表时,它开始立即销毁委托,而无需查看cacheBuffer。
  • 如果将“ height:root.height”替换为“ height:listView.height”,它将在开始时为所有模型项创建委托。

这种行为正常吗?我可以以某种方式更改它吗?

您可以自己尝试:

import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Window 2.11

import Qt.labs.calendar 1.0

Window {
    id: root

    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    ListView {
        id: listView

        anchors.fill: parent
        snapMode: ListView.SnapOneItem
        cacheBuffer: 0

        model: 10

        delegate: Rectangle {
            width: parent.width
            height: root.height
            // height: listView.height
            border.color: "black"

            Text {
                anchors.centerIn: parent

                text: modelData
            }

            Component.onCompleted: {
                console.log("Delegate completed")
            }

            Component.onDestruction: {
                console.log("Delegate destruction")
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

替换

 delegate: MyVeryComplexDelegate {
 }

作者

delegate: Loader {
    width: expectedDelegateWidth
    height: expectedDelegateHeight // Otherwise you might create all...
    sourceComponent: MyVeryComplexDelegate {
    }
    active: someCriteriaYouFeelGoodAbout()
}

现在,您的缓存中将只有简单的Loader,并且您可以确定缓存中哪些是活动的。


可能更好:将MyVeryComplexDelegate的某些部分按ListView的要求进行加载,然后将最复杂的部分隐藏在Loader之后,只有当您确实需要全部复杂性时才可以激活


就您的奇怪发现,据我所知:

关于root.heightlistView.height之间的区别,解释是一个存在许多问题的问题:

虽然root.height引用了您已明确设置的窗口属性height,但是listView.heightanchors.fill: parent确定,这导致将高度设置为{{ 1}}-最初是root.contentItem.height。因此,最初都具有0的高度的代表,都将适合视图,因此必须创建它们,即使您加载得尽可能懒。稍后,它们将与0一起调整大小,其中一些将再次销毁。

您可以看到,在监视代表和root.contentItem

的高度变化时

接下来的事情是,即使委托从一开始就真正地填充了ListView,也会实例化另一个委托。原因是ListView用来创建新委托的条件。为此,高度的总和必须比ListView 。当它等于高度时,就无法实现。

将代表的ListView增加几分之一像素,就可以了。

height