Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Updating Images in a Listvview from a Cache

I'm loading all my images aynchronously in an single cache for my listview.  My problem is that when the imageview first loads, it loads the default image, but once it completes populating the cache I can't send a signal to the update item for it to refresh its image.    it doesn't trigger an item refresh until the item is recycled - and only then does it grab the image.

 

How do I send a signal to a specific item in a listview to trigger an image change or how do I access a specific item's image from the listview to change it?

---
If you find my post helpful please "like" it and "accept as a solution"
Developer
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Updating Images in a Listvview from a Cache

Everything in a ListView should be by way of changes to the model, so you should have the model contain information that effectively defines the image location or content, and then update the model. Depending on the model, this may involve a replace() call, or something else. Internally the model issues an itemUpdated() signal which tells the ListView to re-check that entry and refresh the visual node which is currently being used to render that particular item.

How this would work with your cache I'm not certain.

Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
Developer
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Re: Updating Images in a Listvview from a Cache

I implemented my cache like this in my datamodel emitting the update

void NewGalleryModel::cacheImage(int num){

	bb::ImageData imageData = mimageScaling->resultAt(num);
	Image im = Image(imageData);
	mImageGalleryCache.insert(num,im);
	QVariantMap itemMap = mImageGalleryData.at(num).toMap();
	QString Url=itemMap.value("thumbURL").toString();
	mImageGalleryHash[Url]=num;
	qDebug() << "Num"<< num;
	QVariantList indexPath;
	indexPath << QVariant::fromValue(num);
	qDebug()<< "CacheImage" <<indexPath;
	emit itemUpdated(indexPath);
}

  and here is where I update the image in the Listview

    ImageView {
        id: imageviewID

        image:rootcontainer.ListItem.view.dataModel.getImage(ListItemData.thumbURL)
}

 I assumed as you indicated that updateItem would refresh the visual item.  I have confirmed that the datamodel receives the onUpdateItem but no update occurs to the visual items in the list.  I have also confirmed that the indexPath is correct:

 

Debug: CacheImage (QVariant(int, 0) )  

 

The list does eventually update after it recycles.  I just can't get the listitem to update.  onUpdateItem doesn't seem to update the listview by default.  Am I doing something wrong?

---
If you find my post helpful please "like" it and "accept as a solution"
Developer
Posts: 54
Registered: ‎05-23-2012
My Device: Developer
My Carrier: Developer

Re: Updating Images in a Listvview from a Cache

[ Edited ]

I solved this problem by adding an extra item type, and overriding the itemType() method in QML. I've implemented my own DataModel. I initially populate my list with a bunch of empty dummy items, once the data comes back from the network (or attached QNetworkDiskCache), I emit the itemsChanged() signal from my model, which causes the itemType() QML function to be called again, at which point I switch the ListItem to use the final ThumbItem components. This ThumbItem contains a WebImageView which loads the image (see 

https://github.com/RileyGB/BlackBerry10-Samples/tree/master/WebImageViewSample).

 

                ListView {
                    id: mainListView
                    dataModel: mainListDataModel
                    listItemComponents: [
                        ListItemComponent {
                            type: "item"
                            ThumbItem {
                            }
                        },
                        ListItemComponent {
                            type: "loading"
                            ThumbItemLoading {
                            }
                        }
                    ]
                    // itemsChanged() signal in DataModel does cause this to be called again.
                    function itemType(data, indexPath) { 
                        if (data.ContentId == "")               // If dummy item, use loading ListItemComponent.
                            return "loading";
                        else
                            return "item";
                    }
                }

 

----
I know exactly where the problem *might* be.