Forum Xamarin.Android

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

ListView row re-use

Hi. I am new to the android world. I started with the sample application which shows a list of items. For that purpose I implemented a custom adapter which extends the BaseAdapter class. Items in the list which is shown in the ListView are of different types but they all extend the same base type(something like, Person, Employee, Employer ...). The few articles that I read on the topic stated that I should re-use the listview rows in order to reduce the memory consumption. So my question is: How can I re-use the View passed to the GetView(...) method of my adapter, since I don't know which view it is. What I mean is: The view passed to the method could have been used to render an employee instance but I need to render an employer and I want the two instances to be rendered differently. Any advice will be appreciated.

Uros

Posts

  • TeHaTeHa DEMember ✭✭✭

    Re-Use means, that you don't inflate the view twice. In the getView method you get a view passed in. For the first few items this view in null, after you scroll the list you get the view that is scrolled out and you can re-use this one:

    getView(...., View v, ....)
    {
      if(v == null)
        // instantiate the View
    
      // Fill the Layout with new values
    }
    

    The problem you talked about, is that your item layouts are not identical. So you maybe can made them identical. When you need an extra row for an employee you can set this extra row to visibility.gone for all other items.

    getView(int position, View v, ...) 
    {
      // ...
      if(items[position] instanceof Employee)
        v.findViewById(...).Visibility = ViewStates.Visible;
      else
        v.findViewById(...).Visibility = ViewStates.Gone;
      // ...
    }
    

    But as you might know, this is not the best solution, because you have to re-inflate the layout to find the views. That's because you can use the ViewHolder-Pattern.

    class AdapterClass : BaseAdapter
    {
      private class ViewHolder : Java.Lang.Object
      {
        public TextView tv1;
        public TextView tv2;
        public ImageView iv1;
      }
    
      public override View GetView (int position, View v, ViewGroup parent)
      {
        ViewHolder holder = null;
        if (v == null) 
        {
          v = new View ();
          holder = new ViewHolder ();
          holder.iv1 = v.FindViewById (1);
          holder.tv1 = v.FindViewById (2);
          holder.tv2 = v.FindViewById (3);
        }
    
        if (holder == null)
          holder = (ViewHolder)v.Tag;
    
        //go on work with the ViewHolder
    
        return v;
      }
    }
    
  • UroBregarUroBregar USMember

    Tobias thank you for the explanation and the provided link.

    Uros

Sign In or Register to comment.