自定义适配器中 ViewHolder 的实用程序

Utility of ViewHolder in a custom Adapter

ViewHolder 在自定义 Adapter 中的用途是什么?

我已经使用 ViewHolder 创建了一个 Adapter 和另一个没有使用的,我得到了相同的结果...那么这个有什么用呢?


这是我的 CustomAdapter.classViewHolder :

public class CustomAdapter extends ArrayAdapter<Fruit> {

    public class ViewHolder {
        TextView txtName;
        TextView txtColor;
    }

    CustomAdapter(Context context, ArrayList<Fruit> data) {
        super(context, R.layout.item_fruit, data);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        final Fruit fruit = getItem(position);

        ViewHolder viewHolder = new ViewHolder();

        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.item_fruit, parent, false);
        }

        viewHolder.txtName = (TextView) convertView.findViewById(R.id.textView_fruit_name);
        viewHolder.txtColor = (TextView) convertView.findViewById(R.id.textView_fruit_color);

        if (fruit != null) {
            viewHolder.txtName.setText(fruit.getName());
            viewHolder.txtColor.setText(fruit.getColor());
        }

        return convertView;
    }
}

这是我的 CustomAdapter.class 没有 ViewHolder :

public class CustomAdapter extends ArrayAdapter<Fruit> {

    CustomAdapter(Context context, ArrayList<Fruit> data) {
        super(context, R.layout.item_fruit, data);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        final Fruit fruit = getItem(position);

        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.item_fruit, parent, false);
        }

        TextView txtName = (TextView) convertView.findViewById(R.id.textView_fruit_name);
        TextView txtColor = (TextView) convertView.findViewById(R.id.textView_fruit_color);

        if (fruit != null) {
            txtName.setText(fruit.getName());
            txtColor.setText(fruit.getColor());
        }

        return convertView;
    }
}

要正确使用 ViewHolder,您需要将代码更改为:

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

    final Fruit fruit = getItem(position);

    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.item_fruit, parent, false);
        convertView.setTag(new ViewHolder(convertView));
    }

    ViewHolder viewHolder = (ViewHolder) convertView.getTag();

    viewHolder.txtName = (TextView) convertView.findViewById(R.id.textView_fruit_name);
    viewHolder.txtColor = (TextView) convertView.findViewById(R.id.textView_fruit_color);

    if (fruit != null) {
        viewHolder.txtName.setText(fruit.getName());
        viewHolder.txtColor.setText(fruit.getColor());
    }

    return convertView;
}

你的 ViewHolder 会是这样的:

private class ViewHolder {
    public TextView txtName;
    public TextView txtColor;

    public ViewHolder(View view) {
        txtName = (TextView) view.findViewById(R.id.txt_name);
        txtColor = (TextView) view.findViewById(R.id.txt_color);
    }
}

调用 findViewById() 很昂贵,每次调用 getView() 时根据您的视图调用它会浪费很多时间。

使用 ViewHolder 的唯一优点是通过在重用视图时不调用 findViewById() 来节省时间,即当 convertView 不是 null 时。