Optimizing the ListView

In order to make scrolling through out lists as smooth as possible, we need to ensure that the construction and manipulation of the items run as fast and as efficiently as possible.

How to do it...

One way in which we can optimize the list items is to reuse the item view:

  • This is very easy to do, and all we need is to check is whether we can use the convertView parameter before trying to create a new instance of the item:
    if (convertView == null) {
      var inflater = LayoutInflater.From(context);
      convertView = inflater.Inflate(
        Resource.Layout.ListItemLayout, parent, false);
    }
    var firstRow = convertView.FindViewById<TextView>(
      Resource.Id.firstRow);
    firstRow.Text = person.Name;

Another way is to store references to the various subviews so that we don't have look for them each time, as follows:

  1. Create a type that will hold a reference to those subviews:
    private class ViewHolder : Java.Lang.Object {
      public ImageView Icon;
      public TextView FirstRow;
      public TextView SecondRow;
    }
  2. Then, when we inflate the view for the first time, we search for the various views and store them in the fields:
    var viewHolder = new ViewHolder {
      Icon = convertView.FindViewById<ImageView>(
        Resource.Id.icon),
      FirstRow = convertView.FindViewById<TextView>(
        Resource.Id.firstRow),
      SecondRow = convertView.FindViewById<TextView>(
        Resource.Id.secondRow)
    };
  3. Once we have created the view holder object, we can assign it to the list item's view using the Tag property:
    convertView.Tag = viewHolder;
  4. Next time we have to populate the view, we don't have to search for the various subviews, but we can just get the references from the item:
    var viewHolder = (ViewHolder)convertView.Tag;
  5. When we want to update the item, all we have to do is use the viewHolder object:
    viewHolder.FirstRow.Text = person.Name;

How it works...

As the user is able to scroll quite fast through a list, the list needs to be able to create and update the items as fast as possible. If there is any delay, the user will notice it immediately and this makes the experience less polished.

There are two very common, and incidentally, very expensive operations that we perform for every item. These operations are inflating the views and locating the particular subviews. Every item has to be created at some point, and in order to update, the text of one item will have to find the view that will contain that text. Also, as there may be thousands of items, this executes multiple times in a second.

Tip

The construction or inflation of views as well as searching for views in a hierarchy are very expensive and some of the most common operations performed by any app.

There are a few ways in which we can improve list and app performance, one being in the construction of the view. Instead of reconstructing the view for each item, we need to try and reuse the already existing view. An item scrolling off the screen is placed in a recycle bin in order that the item may be reused at some point. This recycle bin allows Android to limit the number of items constructed, improving both memory consumption as well as the number of CPU operations.

Android provides an easy means to reuse a view in the GetView() method. One of the parameters passed into this method, the convertView parameter, is an available view from the recycle bin. We can then use this view and simply update the contents with the data from the new item. As this view is actually an existing item that scrolled off the screen, we need to ensure that we reset any values that we may have set. This pattern is called Virtualization.

Tip

View construction performance can be improved by reusing old views.

Another way to improve performance is to reduce the number of times we search for a view within the item. Even though we may only have a few views to update in the item, we need to remember that there may be many items, and searching for a view requires that the entire item hierarchy be searched.

We can limit the number of times we search for a view by saving the references to each view item in the item itself. We can do this by creating an object that will hold the references to all the views that we will update and then assign that object to the item. We assign the object to the item by assigning the object to the Tag property of the item's view. We call this pattern the View Holder pattern.

Tip

View finding performance can be improved by storing references to the various subviews when they are found.

There's more...

There are many other performance improvements that we can do for lists. We can cache various pieces of data, such as images. We can also move expensive operations to another thread. This can be further improved by ensuring that we don't run operations unnecessarily, such as when the list is scrolling at high speed. We can also improve performance by ensuring that some of the operations are done beforehand, and the results are cached.

See also

  • The Using custom ListView items recipe
  • The Using a BaseAdapter with arbitrary data recipe
  • The Enabling fast scrolling recipe
  • The Using section indexes recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset