How To Improve Android ListView Performance

ListView is widely used in android application. It is used to show a list of data in rows. And the row data is retrieved from data adapter’s getView() method. You can read article¬†Android ListView Example to learn how to use ListView.

When there are so many list data need to be displayed in the ListView, the getView() method will be called so many times and very frequently. So you may find the ListView performance decreased very fast if the list data is so huge.

So the key to improve ListView performance is to make the getView() method run as quickly as possible. Make it less cost memory and CPU resources. Below picture is the diagram of how the ListView behaves.

listview execution diagram

From above picture, we can see that ListView will cache scraped view objects which can be used later, this will decrease view creation times and reduce view creation consumed resources.

So there are below methods that can be used to improve ListView performance.

1. Only Inflate The View When It Is Null In getView() Method.

Each time ListView show a row, it will call data adapter’s getView(int itemIndex, View itemView, ViewGroup viewGroup) method.

This method will inflate a View object and return it. But the inflate layout xml file process is resource consumed. So we should reduce such inflate layout xml code.

This method has three input parameters. The first parameter is current row index. The second parameter is the scrapped view object if user has already scrolled to that row data before.

READ :   Android ExpandableListView Example

So we should only create the return view when the itemView is null, otherwise return the itemView instead.

Below code is an example.

public View getView(int itemIndex, View itemView, ViewGroup viewGroup) {

    if(itemView == null)
    {   // First inflate the RelativeView object.
        itemView = LayoutInflater.from(ListViewActivity.this).inflate(R.layout.activity_list_view_base_adapter, null);
    }

    // Find related view object inside the itemView.
    ImageView imageView = (ImageView)itemView.findViewById(R.id.baseUserImage);
    TextView titleView = (TextView)itemView.findViewById(R.id.baseUserTitle);
    TextView descView = (TextView)itemView.findViewById(R.id.baseUserDesc);

    // Set background color by row number.
    int colorPos = itemIndex % 2;
    if(colorPos==0) {
        itemView.setBackgroundColor(Color.YELLOW);
    }else
    {
        itemView.setBackgroundColor(Color.GREEN);
    }
    // Set resources.
    imageView.setImageResource(R.mipmap.ic_launcher);

    final String title = titleArr[itemIndex];
    final String desc = descArr[itemIndex];
    titleView.setText(title);
    descView.setText(desc);

    return itemView;
}

2. Use ViewHolder Inner Class To Decrease Find View Times.

From the example code in section 1, we can see that the code will find three view objects ( one ImageView and two TextView ) in each row getView() method. This action is also resource consumption because the find view object action will go through the layout xml tree for each time.

So we should reduce such find view object action. We can find the view object just for the first time and store them in a View Holder class, which can be used for later process.

public View getView(int itemIndex, View itemView, ViewGroup viewGroup) {

        if(itemView == null)
        {   // First inflate the RelativeView object.
            itemView = LayoutInflater.from(ListViewActivity.this).inflate(R.layout.activity_list_view_base_adapter, null);

            // Find related view object inside the itemView.
            ImageView imageView = (ImageView)itemView.findViewById(R.id.baseUserImage);
            TextView titleView = (TextView)itemView.findViewById(R.id.baseUserTitle);
            TextView descView = (TextView)itemView.findViewById(R.id.baseUserDesc);

            // Only create the view holder to hold the child view if the itemView is null.
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.setImageView(imageView);
            viewHolder.setTitleView(titleView);
            viewHolder.setDescView(descView);

            // Save the ViewHolder object in cached view.
            itemView.setTag(viewHolder);
        }

        // Set background color by row number.
        int colorPos = itemIndex % 2;
        if(colorPos==0) {
            itemView.setBackgroundColor(Color.YELLOW);
        }else
        {
            itemView.setBackgroundColor(Color.GREEN);
        }

        // Get the ViewHolder class from the cached view. 
        ViewHolder viewHolder = (ViewHolder)itemView.getTag();
        // Set resources.
        viewHolder.getImageView().setImageResource(R.mipmap.ic_launcher);

        final String title = titleArr[itemIndex];
        final String desc = descArr[itemIndex];
        viewHolder.getTitleView().setText(title);
        viewHolder.getDescView().setText(desc);

        return itemView;
    }

    // This class is used to hold ListView row view's child view object.
    class ViewHolder{
        // Store image view.
        private ImageView imageView;
        // Store title text view.
        private TextView titleView;
        // Store desc text view.
        private TextView descView;

        public ImageView getImageView() {
            return imageView;
        }

        public void setImageView(ImageView imageView) {
            this.imageView = imageView;
        }

        public TextView getTitleView() {
            return titleView;
        }

        public void setTitleView(TextView titleView) {
            this.titleView = titleView;
        }

        public TextView getDescView() {
            return descView;
        }

        public void setDescView(TextView descView) {
            this.descView = descView;
        }
    }
};

3. Reduce Network Or IO Interaction In getView() Method.

Network interaction is time consumption. And IO operation is resource consumption also. But commonly ListView’s row data is retrieved from network or local file by IO.

READ :   Android RecyclerView Example

So we should use a thread to interact with the network server, and let’s that thread to update the added view row data in memory. And the getView() method will get row data from the memory variable.

The IO operation should be placed in the method when the activity is initialized such as activity’s onStart() method. And the retrieved data from local file will be cached in memory also.

With all above actions, your ListView performance can be improved as much as you need.

(Visited 310 times, 1 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.