Forum Xamarin Xamarin.Forms

Loading images via ListView ItemAppearing event

RD8RD8 USMember
edited October 2016 in Xamarin.Forms

I'm trying to make use of @JamesMontemagno's example but to trigger the download of images as the user scrolls.

I'm using a ViewModel for the page with an ObservableCollection of MyItem (MyItems)
One of the properties of MyItem is an ObservableCollection of Photo (Photos)

The ItemSource of my ListView has a binding to MyItems and the ListView item template contains an Image control with a binding to the first Photo in the nested collection.
<Image Grid.Row="0" Grid.Column="0" Source="{Binding Photos[0].Image}" Aspect="AspectFit" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />

In my page code behind the ItemAppearing event handler is...
private void ListViewProperties_ItemAppearing(object sender, ItemVisibilityEventArgs e) { var item = e.Item as MyItem; item.GetPrimaryPhoto(); }

The method in the MyItem class...
public void GetPrimaryPhoto() { if (NumPhotos > 0 && Photos[0].Image == null) { Photos[0].GetImage(); OnPropertyChanged("Photos"); } }

and the in the Photo class...
` public String ImageURL { get; set; }

    public UriImageSource Image { get; set; }

    public void GetImage()
        Image = new UriImageSource
            Uri = new Uri(ImageURL),
            CachingEnabled = true,
            CacheValidity = new TimeSpan(3, 0, 0, 0) // -- cache for 3 days

This seems to work more or less as I'd like, aside from the images seem to reload (even when cached and in flight mode) as you scroll the ListView and an occasional debug error about the collection being modified.

My core aim is to download the collection of MyItem from a web service with the Photos including the Url (which I'm writing to SQLite) and then have the app download the images only when the user views the list. They'll be able to tap in to an item to view a details page and any additional photos. I'm using UriImageSource as I've got the impression this allows me to cache images the app has downloaded that the user can potentially still then view while their device is offline.

I originally just implemented the code within GetImage() as the get method of the public property. I've seen it suggested this is an async call already. Is that correct? I'd like the ListView page to render as quick as possible and not have to wait till it's loaded all the images.

Would appreciate any advice on how I might improve or optimise this code. Am I close?
Thanks in advance of your kind response.


Sign In or Register to comment.