Question

I'm currently working on part of an app which shows a news snippet next to an image (if an image exists). This list of news is part of a SegmentedControl "tab" page, and may be hidden and re-shown as required by the user. As the images are loaded over the network, they are handled by an ImageTracker and only set as a property once fully loaded.

The problem I'm having is that while these images load fine first time, these images then disapprear if I navigate away to a different SegmentControl "tab" and then navigate back to the News tab. The act of hiding is done by setting the visibility of non-active containers to false, and setting the visibility of the active container to true.

This is how I'm defining the data bindings: ListView { id: lstShowNews objectName: "lstShowNews"

    listItemComponents: [
        ListItemComponent {
            type: "item"      
            Detail_Tabs_NewsCell {
                newsHeadline: ListItemData.headline
                newsBlurbPreview: ListItemData.content
                newsTimeAdded: ListItemData.time    
                newsImageVisible: ListItemData.hasImage
                newsImage: ListItemData.image                              
            } 
        }
    ]
}

The aliases/properties for the custom list item:

property alias newsImageVisible: newsImage.visible
property alias newsHeadline: newsTitle.text
property alias newsImage: newsImage.image
property string newsBlurbPreview: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam condimentum tellus vel magna dapibus aliquam. Nunc iaculis metus ut arcu tempus semper."
property string newsTimeAdded: "News Source - 3 hours ago"

The section of C++ code that handles the loading of the list:

/*!
 * Handles loading for each tab page. Enables data to only be loaded on demand.
 * @param index - The new selected index on the SegmentedControl
 */
void MyClass::onSegmentChanged(int index) {
if(index == 2) {
    if(!mNewsLoaded) {
        // Load the news
        NewsRequester* news = new NewsRequester(mId);
        connect(news, SIGNAL(requestDone(QList<NewsItem*>)), this, SLOT(onNewsReceieved(QList<NewsItem*>)));
        indNews->start();         // Activity indicator
        news->requestNews();
    }
    else {
      // Caching functions
    }
}
else {
    // Stuff for other tabs
}
}

void MyClass::onNewsReceieved(QList<NewsItem*> newsItems) {
    qDebug() << "Received news reply";
    indNews->stop();
    indNews->setVisible(false);

    mNewsItems = newsItems;
    setNewsModel();

}

void MyClass::setNewsModel() {
GroupDataModel* newsModel = new GroupDataModel(QStringList() << "news");
newsModel->setGrouping(ItemGrouping::None);

// Move the list items to the data model
for(int i = 0; i < mNewsItems.size(); i++) {
    mNewsItems.at(i)->loadImage();
    newsModel->insert(mNewsItems.at(i));
}

ListView* lstNews = root->findChild<ListView*>("lstShowNews");
lstNews->setDataModel(newsModel);
}

Functionality for tracking the image and ensuring it's loaded properly before being passed to the list:

/*!
 * Tracks the status of the current local image and displays when ready
 */
void NewsItem::trackImage() {
// Load cascades image
mTracker = new ImageTracker(mLocalImage);
connect(mTracker, SIGNAL(stateChanged (bb::cascades::ResourceTracker::State)),
        this, SLOT(onStateChanged (bb::cascades::ResourceTracker::State)));
}

/*!
 * Passes the downloaded image's path to the list
 */

void NewsItem::onImageRetrieved(QString path) {
//qDebug() << "Received image " << path;
mLocalImage = QUrl(path);
trackImage();
}

/*!
 * Display the image if it's been fully loaded in memory
 */
void NewsItem::onStateChanged(bb::cascades::ResourceTracker::State state) {
if(state == bb::cascades::ResourceTracker::Loaded) {
    qDebug() << "Image loaded";
    mLocalCascadesImage = mTracker->image();
    emit localImageChanged();
}
}

Property for mLocalCascadesImage:

Q_PROPERTY(bb::cascades::Image image READ localImage NOTIFY localImageChanged)

Is there any reason as to why the ListView would misbehave in this way? Thanks.

Was it helpful?

Solution

Solved it myself. Turns out I also needed to expose the newsImage.imageSource property and pass it the path to the locally-cached version of the image, if available. While the image property is handy for ensuring images appear as soon as they have been downloaded, the imageSource property needs to be used for locally-available files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top