【问题标题】:qml listview image caching doesn't work as expectedqml listview 图像缓存无法按预期工作
【发布时间】:2017-11-15 06:45:37
【问题描述】:

我创建了一个包含图像的列表视图,当向下滚动时会自动请求新项目。我正在使用 Image 组件来显示来自 url 源的图像。问题是图像一旦加载就不会缓存在内存中。当我向下滚动时我可以看到它们,但是当我返回时我必须等待它们再次加载。有没有办法来解决这个问题?图像组件有一个属性缓存,但它没有做任何改进。我知道在 Android 中这是以完全相同的方式完成的,并且一旦下载,图像就会保存在内存中。 这是一个示例代码:

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    id: rootId

    property url fullImageUrl
    property string tag : "windsurfing"

    XmlListModel{
        id : modelId
        namespaceDeclarations: "declare namespace media = 'http://search.yahoo.com/mrss/';"
        source: "http://api.flickr.com/services/feeds/photos_public.gne?format=rss2&tags="+tag
        query: "//item[title and media:thumbnail and media:content]"
        XmlRole{name:"fullImage"; query:"media:content/@url/string()" }
    }

    TextField{
        id : userValueId
        font.pointSize: 14
        width: parent.width
        height : implicitHeight
        placeholderText: "Enter a Flickr Tag"
        onEditingFinished: tag = text
    }

    ListView{
        id : listViewId
        anchors.fill: parent
        anchors.topMargin: userValueId.height + 10

        Layout.minimumWidth: 400
        Layout.maximumWidth: parent.width - 50
        model: modelId
        delegate:  delegateId
    }

    Component{
        id: delegateId
        Rectangle{
            id :itemId
            height : 300
            width : 500
            Image{
                id : imageId
                source : fullImage
                anchors.fill: parent
                fillMode: Image.Stretch
                cache: true
            }
        }
    }
}

【问题讨论】:

    标签: image qt listview caching qml


    【解决方案1】:

    如何缓存模型提供并绘制的图形项 QML 列表视图?

    我会尝试使用以像素为单位指定的 ListView cacheBuffer 属性以适应代表。如果您的代理在滚动方向上是 300 像素(例如,高度并且您垂直滚动),那么每行有一个代理,“缓存缓冲区”有 10000 像素,那么它最多可以容纳 33 个代理。

    ListView {
        id : listViewId
        anchors.fill: parent
        anchors.topMargin: userValueId.height + 10
        cacheBuffer: 10000 // pixels in direction of scrolling the view,
                           // saves a bit of processing just by caching
                           // delegates content in memory, causes async
                           // read-ahead for images outside of view area
        Layout.minimumWidth: 400
        Layout.maximumWidth: parent.width - 50
        model: modelId
        delegate: delegateId
    }
    

    如果内存量受到严格限制,那么指定合理的小缓存缓冲区是有意义的,例如2 页的列表视图可防止过多的预读。缓存并不能保证不会再次读取数据。 我也怀疑使用 Component 是否是图像缓存的正确方法,但我得出结论,只要该组件的代码中没有加载器在任意时间执行加载,它就不会影响事情。 em>

    您也可以尝试在 C++ 中实现自己的image provider 以显式控制图像下载/缓存,因此逻辑将完全由您的代码控制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 2016-05-02
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      相关资源
      最近更新 更多