0

I make a gridview which load images from url. Its working good but it is very slow.I think its make user irritated.

In my code i am using Bitmap in GridView adapter . Here is my code

using System;
using Android.Widget;
using Android.App;
using System.Collections.Generic;
using Android.Views;
using Android.Graphics;
using System.Net;

namespace AMUSEAndroid
{
public class GridViewAdapter : BaseAdapter<ImageItem> 
{
    Activity context;
    List<ImageItem> items;

    public GridViewAdapter (Activity context, List<ImageItem> gridViewtems)
    {
        this.context = context;
        this.items = gridViewtems;
    }

    public override int Count {
        get { return items.Count; }
    }

    public override ImageItem this[int position]
    {
        get { return items[position]; }
    }

    public override long GetItemId (int position)
    {
        return position;
    }

    public override View GetView (int position, View convertView, ViewGroup parent)
    {
        View view = convertView;
        var item = items[position];
        if (view == null)
            view = context.LayoutInflater.Inflate(Resource.Layout.player_grid_item, null);
        ImageView imgIcon =  view.FindViewById<ImageView> (Resource.Id.img_play_bg);//.SetImageBitmap (gridViewtems[position]);
        view.FindViewById<TextView> (Resource.Id.music_text).Text = item.Heading;


        var imageBitmap = GetImageBitmapFromUrl(item.ImageResourceId);
        imgIcon.SetImageBitmap(imageBitmap);

        return view;

    }

    public Bitmap GetImageBitmapFromUrl(string url)
    {
        Bitmap imageBitmap = null;

        using (var webClient = new WebClient())
        {
            var imageBytes = webClient.DownloadData(url);
            if (imageBytes != null && imageBytes.Length > 0)
            {
                imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
            }
        }

        return imageBitmap;
    }
}

}

Here ImageItem is a Model class.

Is there any other way to load image from url in Gridview. Which load images very quickly and make application faster.

Thanks in advance.

Orkun Kocyigit
  • 1,137
  • 10
  • 21
Bikash
  • 477
  • 1
  • 4
  • 16

2 Answers2

1

Yup, there is.

You need asynchronous image loading. The current state-of-the-art in this task is implmented by Square's Picasso.

I have never coded in Xamarin, but a quick search shows me there is a module for Xamarin Picasso.

Community
  • 1
  • 1
Boris Strandjev
  • 46,145
  • 15
  • 108
  • 135
0

I use this:

private async Task<Bitmap> GetImageBitmapFromUrl(string url)
    {
        Bitmap imageBitmap = null;

        using (var webClient = new WebClient())
        {
            var imageBytes = await webClient.DownloadDataTaskAsync(url);
            if (imageBytes != null && imageBytes.Length > 0)
            {
                imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
            }
        }

        return imageBitmap;
    }

But I cache all images using a dictionary:

private static Dictionary<string, Bitmap> autoCompleteImages = new Dictionary<string, Bitmap>();

And on GetView method I use "holderView" and this piece of code to get cached images from dictionary:

if (autoCompleteImages.ContainsKey(this.autocompleteSearches[position].PicUrl))
            {
                holder.imageView.SetImageBitmap(autoCompleteImages[this.autocompleteSearches[position].PicUrl]);
            }
            else
            {
                this.UpdateImage(holder, position);
            }

Here UpdateImage method:

private async void UpdateImage(ViewHolderAutoComplete holder, int position)
    {
        autoCompleteImages[this.autocompleteSearches[position].PicUrl] = await GetImageBitmapFromUrl(this.autocompleteSearches[position].PicUrl);
        holder.imageView.SetImageBitmap(autoCompleteImages[this.autocompleteSearches[position].PicUrl]);
    }
SergioZgz
  • 148
  • 5
  • Thanks its really helpful . But i prefer mostly Picasso. – Bikash Dec 02 '15 at 12:28
  • Yes you are right. One of my friend is using your solution. You rock buddy.. :D. Many many thanks for the solution.. :D – Bikash Dec 02 '15 at 12:55
  • U're welcome :) and remember if you like it please vote for it ;) – SergioZgz Dec 02 '15 at 13:01
  • @Bikash, don't do this please. Overall reinventing the wheel is always a bad idea and there is a reason.why Square defined entire library for that. I do understand the whim to implement and control everything yourself, it took me long time to get over. – Boris Strandjev Dec 02 '15 at 14:01
  • Boris if you think that... then dont use your solution or mine... just use mvvmcross with mvxlistview and mvximage with download cache... I think that the correct way is understand how to do that and then if you want, search and use that framework which can help you. With this code for example you could undestand what do you need to change if you need add a custom header to request the image from a server... – SergioZgz Dec 03 '15 at 09:24