ListView的奇怪行为

时间:2015-02-02 06:44:46

标签: listview blackberry qt4 qml blackberry-10


我使用以下代码:

ListView {
        id: listView 
listItemComponents: ListItemComponent {

            Container {
                id: listItemContainer
                property string packageId: ListItemData.packageId
                property variant packageDetailsPage
                layout: AbsoluteLayout {

                }
                WebImageView {
                    preferredHeight: 290
                    preferredWidth: 751
                    url: ListItemData.url;  



                 }
    }
}

WebImageView的代码:

//webimageview.hpp
#ifndef WEBIMAGEVIEW_H_
#define WEBIMAGEVIEW_H_

#include <bb/cascades/ImageView>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QUrl>
using namespace bb::cascades;

class WebImageView: public bb::cascades::ImageView {
    Q_OBJECT
    Q_PROPERTY (QUrl url READ url WRITE setUrl NOTIFY urlChanged)
    Q_PROPERTY (float loading READ loading NOTIFY loadingChanged)

public:
    WebImageView();
    const QUrl& url() const;
    double loading() const;

    public Q_SLOTS:
    void setUrl(const QUrl& url);
    void clearCache();

    private Q_SLOTS:
    void imageLoaded();
    void dowloadProgressed(qint64,qint64);

    signals:
    void urlChanged();
    void loadingChanged();


private:
    static QNetworkAccessManager * mNetManager;
    static QNetworkDiskCache * mNetworkDiskCache;
    QUrl mUrl;
    float mLoading;    
    bool isARedirectedUrl(QNetworkReply *reply);
    void setURLToRedirectedUrl(QNetworkReply *reply);
};

#endif /* WEBIMAGEVIEW_H_ */

webimageview.cpp

#include "WebImageView.h"
#include <QNetworkReply>
#include <QNetworkDiskCache>
//#include <QDesktopServices>
#include <bb/cascades/Image>

using namespace bb::cascades;

QNetworkAccessManager * WebImageView::mNetManager = new QNetworkAccessManager();
//QNetworkDiskCache * WebImageView::mNetworkDiskCache = new QNetworkDiskCache();

WebImageView::WebImageView() {

    mLoading = 0;
}

const QUrl& WebImageView::url() const {
    return mUrl;
}

void WebImageView::setUrl(const QUrl& url) {
    // Variables
        mUrl = url;
        mLoading = 0;
        qDebug()<<"url:: "<<mUrl;
        // Reset the image
        resetImage();

        // Create request
        QNetworkRequest request;
        request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
        request.setUrl(url);

        // Create reply
        QNetworkReply * reply = mNetManager->get(request);

        // Connect to signals
        QObject::connect(reply, SIGNAL(finished()), this, SLOT(imageLoaded()));
        QObject::connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(dowloadProgressed(qint64,qint64)));

        emit urlChanged();

}

double WebImageView::loading() const {
    return mLoading;
}

void WebImageView::imageLoaded() {
    // Get reply
    QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
    QObject::disconnect(reply, SIGNAL(finished()), this, SLOT(imageLoaded()));
    QObject::disconnect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(dowloadProgressed(qint64,qint64)));
    if (reply->error() == QNetworkReply::NoError) {
        if (isARedirectedUrl(reply)) {
            setURLToRedirectedUrl(reply);
            return;
        } else {
            QByteArray imageData = reply->readAll();
            setImage(Image(imageData));

        }
    }
    // Memory management
    reply->deleteLater();
}

bool WebImageView::isARedirectedUrl(QNetworkReply *reply) {
    QUrl redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
    return !redirection.isEmpty();
}

void WebImageView::setURLToRedirectedUrl(QNetworkReply *reply) {
    QUrl redirectionUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
    QUrl baseUrl = reply->url();
    QUrl resolvedUrl = baseUrl.resolved(redirectionUrl);

    setUrl(resolvedUrl.toString());
}

void WebImageView::clearCache() {
    //mNetworkDiskCache->clear();
}

void WebImageView::dowloadProgressed(qint64 bytes, qint64 total) {
    mLoading = double(bytes) / double(total);

    emit loadingChanged();
}

我正在使用ListDataModel。以上代码工作正常并加载图像。但是当列表中有超过100个项目时,它会在某些WebImageView中显示错误的图像。当你随机滚动图像改变。我已经在加载了错误图像的项目中检查了webImageView的url属性,但是它有正确的URL。

在此链接中:https://developer.blackberry.com/native/reference/cascades/bb__cascades__listview.html blackberry表示列表视图遵循MVC体系结构,当ListView所拥有的QObject对象滚动到可见区域之外或者ListView本身被删除时,它们将被删除。这是我的问题的原因吗? 如果没有这个代码有什么问题? 请帮忙......

1 个答案:

答案 0 :(得分:0)

如果一个图像加载时间太长,它将在恢复单元格时覆盖新图像。 方法setUrl必须首先取消当前请求(如果正在加载

[In constructor] mNetManager = new QNetworkAccessManager(Application::instance());


void WebImageView::setUrl(const QUrl& url) {
mUrl = url;

//If another URL was loading:
if(reply != 0 && reply->isRunning()){
    disconnect(reply);
    reply->abort();
}

//Chargement
//qDebug() << "WebImageView setUrl " << url;
if(url.isValid() && !url.isEmpty()) {
    if(url.toString().startsWith("asset://")){
        setImageSource(url);
        return;
    }

        setImageSource(mDefaultSource);
        reply = mNetManager->get(QNetworkRequest(url));
        connect(reply,SIGNAL(finished()), this, SLOT(imageLoaded()));
}
emit urlChanged();
}