Android to improve the efficiency of ListView

The reason why the ListView space is difficult to use is because it has many details that can be optimized, of which operating efficiency is a very important point. At present, the operating efficiency of our ListView is very low, because in the getView() method of the FruitAdapter, the layout is reloaded every time. When the ListView scrolls quickly, this will become a performance bottleneck.

A closer look will reveal that there is also a convertView parameter in the getView() method, which is used to cache the previously loaded layout so that it can be reused later.
As you can see, we have now judged in the getView() method. If convertView is null, use LayoutInflater to load the layout. If it is not null, then directly reuse cnvertView. This greatly improves the operating efficiency of the ListView, and can also show better performance when scrolling quickly.
However, at present, our code can still be optimized. Although it will no longer be repeated to load the layout, the findViewById() method of the View is still called every time in the getView() method to obtain an instance of the control.
We can use a ViewHolder to optimize this part of the performance and modify the code in the FruitAdapter as follows:

package net.nyist.lenovo.listviewtest;


import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class FruitAdapter extends ArrayAdapter<Fruit>{
    
    

private int resourceId;

public FruitAdapter(Context context, int textViewResourceId, List<Fruit>objects){
    
    
    super(context,textViewResourceId,objects);
    resourceId = textViewResourceId;
}


@Override
public View getView(int position,  View convertView,  ViewGroup parent) {
    
    
    Fruit fruit = getItem(position);//获取当前项的Fruit实例
    View view;
    ViewHolder viewHolder;
    if (convertView==null){
    
    
        view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
        viewHolder = new ViewHolder();
        viewHolder.fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
        viewHolder.fruitName = (TextView)view.findViewById(R.id.fruit_name);
        view.setTag(viewHolder);//将ViewHolder存储在View中。
    }else {
    
    
        view = convertView;
    }
    ImageView fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
    TextView fruitName = (TextView)view.findViewById(R.id.fruit_name);
    fruitImage.setImageResource(fruit.getImageId());
    fruitName.setText(fruit.getName());
    return view;
}
class ViewHolder{
    
    
    ImageView fruitImage;
    TextView fruitName;
}
}

We added a new internal class ViewHolder, which is used to cache instances of the control. When convertView is null, create a ViewHolder object and store the control instances in ViewHolder, and then call the setTag() method of View to store the ViewHolder object in the View. When convertView is not null, call View's getTag() method, take out ViewHolder again. In this way, all control instances are cached in ViewHolder, and there is no need to obtain control instances through the findViewById() method every time.
After these two steps of optimization, the efficiency of our ListView is already very good.

Guess you like

Origin blog.csdn.net/i_nclude/article/details/75267993