第一行代码学习笔记:Android基础----ListView

ListView的优化

public class Adapter extends ArrayAdapter<Fruit> {
    private int resource = 0;

    public Adapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
        super(context, resource, objects);
        this.resource = resource;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Fruit fruit = getItem(position);
        View view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
        AppCompatImageView fruitImage = view.findViewById(R.id.fruit_image);
        AppCompatTextView fruitName = view.findViewById(R.id.fruit_name); 
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());
        return view;
    }
}

在getView方法中每次都要把布局加载一遍,当ListView快速滚动的时候,会造成性能的瓶颈。方法中的convertView参数用于将之前加载的布局进行缓存,修改代码如下:

 @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Fruit fruit = getItem(position);
        View view ;
        if (convertView == null){
            view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
        }else {
            view = convertView;
        }
        AppCompatImageView fruitImage = view.findViewById(R.id.fruit_image);
        AppCompatTextView fruitName = view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());
        return view;
    }

现在虽然不会重复加载布局,但是还是会调用View的FindViewById()方法来获取一次控件的实例。可以借助ViewHolder 进行优化

 @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Fruit fruit = getItem(position);
        View view ;
        ViewHolder viewHolder;
        if (convertView == null){
            view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.fruitImage = view.findViewById(R.id.fruit_image);
            viewHolder.fruitName = view.findViewById(R.id.fruit_name);
            view.setTag(viewHolder);
        }else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }

        viewHolder.fruitImage.setImageResource(fruit.getImageId());
        viewHolder.fruitName.setText(fruit.getName());
        return view;
    }
    class ViewHolder{
        AppCompatImageView fruitImage;
        AppCompatTextView  fruitName;
    }
内部类ViewHolder用于对控件的实例进行缓存,当convertView为null时,创建ViewHolder对象,并将控件的实例都存放在ViewHolder中,调用View 的setTag()方法将ViewHolder对象存储在View中,当convertView不为null时,通过View的getTag()方法取出ViewHolder,这样所有控件的实例都存储在了ViewHolder中,就没必要每次都通过findViewById()方法来获取控件实例了。

猜你喜欢

转载自blog.csdn.net/zsp45212/article/details/80532618