ListView with online images

PeterZosiakPeterZosiak USMember ✭✭

Hello. I would like to have (in Xamarin Forms) ListView, where ViewCell contains label + image. Image source is from internet url.
So I followed this tutorial http://xforms-kickstarter.com/#organize-lists-of-detail-pages

So in my case its should be something like this:

public partial class FruitPage : ContentPage
        {
            public FruitPage()
            {
                InitializeComponent();
                var listView = new ListView
                {
                    ItemsSource = new List<Recipe> {
                    new Recipe { Heading = "Apple", Description = "Awesome!", Img_Url = "https://diaceps.blob.core.windows.net/recipes/09aad27e-6828-4a06-a39c-2c62ac44282b.jpeg" },
                    new Recipe { Heading = "Banana", Description = "Beautiful!", Img_Url = "https://diaceps.blob.core.windows.net/recipes/09aad27e-6828-4a06-a39c-2c62ac44282b.jpeg" },
                    new Recipe { Heading = "Cherry", Description = "Cheap!", Img_Url = "https://diaceps.blob.core.windows.net/recipes/09aad27e-6828-4a06-a39c-2c62ac44282b.jpeg" },
                },
                    ItemTemplate = new DataTemplate(typeof(FruitCell)),
                    RowHeight = 150,
                };
                listView.ItemTapped += (sender, e) => {
                    listView.SelectedItem = null;
                    Navigation.PushAsync(new FruitDetailPage(e.Item as Recipe));
                };
                Title = "Fruits";
                Content = listView;
            }
        }


        public class FruitCell : ViewCell
            {
                public const int RowHeight = 55;
                public FruitCell()
                {
                    var nameLabel = new Label { FontAttributes = FontAttributes.Bold };
                    nameLabel.SetBinding(Label.TextProperty, "Name");

                    var imagge = new Image();
                    imagge.SetBinding(Image.SourceProperty, "Img_Url");

                    View = new StackLayout
                    {
                        Spacing = 2,
                        Padding = 5,
                        Children = {
                        nameLabel,
                        imagge
                    },
                    };
                }
    }

    public partial class FruitDetailPage : ContentPage
        {
            public FruitDetailPage(Recipe recipe)
            {
                InitializeComponent();
                var embeddedImage = new Image { Aspect = Aspect.AspectFit };
                embeddedImage.Source = ImageSource.FromUri(new Uri(recipe.Img_Url));
                Title = recipe.Heading;
                Content = embeddedImage;
            }
        }

BUT when Application starts, screen is empty (because images are downloading ???) its clickable, everything works fine, but no images.

and when i refresh page, images are displayed correctly.

So my question is. How to solve this problem ? What is the good practise with ListView with online images

Best Answers

Answers

  • ShawnCastrianni.5092ShawnCastrianni.5092 US ✭✭✭
    edited June 2016

    Yes, I think it is loading the images. I had about a 5 second delay the first time I ran your test program. Also, each of the URL's are https so maybe the encryption is slowing things down too?

    My comments on your code:

    1. Your binding to the Heading property in your FruitCell class is wrong since you used the "Name" property which Recipe doesn't have. That is why your output only contains images. the binding failed on the Heading.
    2. The pictures you are pointing too are very large to be shown in every row of a ListView. I would recommend you use 2 different URL's, one for a thumbnail and one for a detail image. The thumbnail url is used for the ListView and the detail url is used for the FruitDetailPage.
    3. You are hardcoding your RowHeight to 150. I recommend never to hardcode any pixel values except for margins and padding. let the Listview size each row for you based on its content. You do that by turning on HasUnevenRows=true
    4. I see that you have InitializeComponent() in your pages. That must mean your are using XAML, however, your code shows all of the UI is done in code and NOT XAML. Therefore, you can remove your XAML pages and the InitializeComponent() method since it isn't doing anything

    I have attached a tweaked version of your sample program that uses 3 different URL's that point to images that are only 64x64 in size.

  • PeterZosiakPeterZosiak USMember ✭✭

    @ShawnCastrianni.5092 said:
    Yes, I think it is loading the images. I had about a 5 second delay the first time I ran your test program. Also, each of the URL's are https so maybe the encryption is slowing things down too?

    My comments on your code:

    1. Your binding to the Heading property in your FruitCell class is wrong since you used the "Name" property which Recipe doesn't have. That is why your output only contains images. the binding failed on the Heading.
    2. The pictures you are pointing too are very large to be shown in every row of a ListView. I would recommend you use 2 different URL's, one for a thumbnail and one for a detail image. The thumbnail url is used for the ListView and the detail url is used for the FruitDetailPage.
    3. You are hardcoding your RowHeight to 150. I recommend never to hardcode any pixel values except for margins and padding. let the Listview size each row for you based on its content. You do that by turning on HasUnevenRows=true
    4. I see that you have InitializeComponent() in your pages. That must mean your are using XAML, however, your code shows all of the UI is done in code and NOT XAML. Therefore, you can remove your XAML pages and the InitializeComponent() method since it isn't doing anything

    I have attached a tweaked version of your sample program that uses 3 different URL's that point to images that are only 64x64 in size.

    Hi Shawn,

    Thank you for your suggestions and hits, I ll definitely implement it, but using smaller (thumbnail) images on web-service side not solving problem of ListView. There must be some way how to "re-write" ListView after images are downloaded or something else how to handle larger images.

  • DanielLDanielL PLInsider ✭✭✭✭
    edited July 2016

    You can replace Image with CachedImage from https://github.com/luberda-molinet/FFImageLoading (API compatible Image replacement). It should help a lot. Also, try set DownsampleToViewSize to true. It will resize your images automatically.

Sign In or Register to comment.