Forum Xamarin.Android

How do I reuse list view rows?

I need a little bit of help with my list view. So far I have it set up to work with a custom adapter that is working fine to generate the list. However if I try to scroll past what is already displayed the app will stall and may result in an error if the user is impatient enough.

Here's the code for my adapter:

public class HomeScreenAdapter : BaseAdapter

{

    NewsObject[] items;

    Activity context;



    public HomeScreenAdapter(Activity context, NewsObject[] items) : base()

    {

        this.context = context;

        this.items = items;

    }



    public override long GetItemId(int position)

    {

        return position;

    }



    public override NewsObject this[int position]

    {   

        get { return items[position]; } 

    }



    public override int Count

    {

        get { return items.Length; } 

    }



    public override View GetView(int position, View convertView, ViewGroup parent)

    {

        var item = items [position];

        View view = convertView;

        if (view == null) // no view to re-use, create new

            view = context.LayoutInflater.Inflate (Resource.Layout.CustomLayout, null);

        view.FindViewById<TextView> (Resource.Id.text1).Text = item.title;



        var str = item.caption;

        var charsToRemove = new string[] { "@", "\\"};

        foreach (var c in charsToRemove)

        {

            str = str.Replace(c, string.Empty);

        }



        view.FindViewById<TextView> (Resource.Id.text2).Text = str;



        var imageBitmap = GetImageBitmapFromUrl (item.image);

        view.FindViewById<ImageView> (Resource.Id.image).SetImageBitmap (imageBitmap);

        return view;

    }



    private 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;

    }

About halfway down I see the note where to add the reuse view. (it's an if statement)
Only problem is I don't know what it requires to reuse the view -_-'

Could anyone help shed some light for me?

Best Answer

Answers

  • CheesebaronCheesebaron DKInsider, University mod

    What error do you get? My guess is that because you are loading the images on the UI thread the scrolling in the ListView will feel sluggish and might eventually crash because you don't dispose of your Bitmap instances.

  • KlutchSCKlutchSC USMember

    There is no "error" I get in the app.
    take for instance a list of 5 objects that all display on screen with clipping on the bottom on. I can scroll the listview to finish reading my last item in on the list. However if there were 6 items and the list with the final one not being displayed at all, the scrolling will work smoothly until the bottom of the 5th element is reached (much like above) but then will stall until the next item is loaded (usually 2 or 3 seconds). Once it is the scrolling will work fine for that entry but once again it must pause and load to get the next one (a seventh or eighth entry). It even stalls when trying to scroll back to the previous entries that I have passed.

    The error I referred to is only that when I build it and run the app, continually scrolling during the stall (much like an angry user would do) resorts in a Force Stop error message that will even itself out if I choose wait, but it's still a bug I don't want in there.

    What does it mean to be loading on the UI thread and should I not be doing it?
    And what should I be doing to dispose of my Bitmap instances to speed this up?

  • KlutchSCKlutchSC USMember

    I'm still a bit confused. I tried to swap out my GetView with the one featured in the comment to try and get it working with mine but it is telling me many of the things do not exist in the current context. I am by no means trying to steal the work, but rather trying to get a better understanding of what it is trying to do but cannot figure out what is going on.

    I replaced my last lines with ones you provided above which was as easy as including the "Using" in front of the lines. Can you maybe explain what that is meant to do differently?

  • CheesebaronCheesebaron DKInsider, University mod

    It disposes of the C# handle of the Bitmap, since it does not keep that handle, the Java side can garbage collect the Image data when it wants. If the Bitmap is not disposed on the C# side, the reference is kept around to the Java side and the Image data will not be collected and kept around in the memory. Loading enough images will make the app crash.

Sign In or Register to comment.