解释 ListView 中 convertView 和 View Holder Pattern 的各自作用

Explain individual role of convertView and View Holder Pattern in ListView

谁能解释一下convertView和ViewHolder Pattern在ListView中各自的作用,以及它们如何提高listview的效率?

private class PersonsAdapter extends ArrayAdapter<Person> {

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

        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_entry, null);
            holder = new ViewHolder();
            holder.nameTextView = (TextView) convertView.findViewById(R.id.person_name);
            holder.surnameTextView = (TextView) convertView.findViewById(R.id.person_surname);
            holder.personImageView = (ImageView) convertView.findViewById(R.id.person_image);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        Person person = getItem(position);

        holder.nameTextView.setText(person.getName());
        holder.surnameTextView.setText(person.getSurname());
        //holder.personImageView.setImageBitmap(person.getImage());

        return convertView;
    }
}

SO中有很多关于这个的帖子。 但简而言之,它是关于重用 ListView 中的对象而不是实例化新对象。 在 ListView 中,屏幕上有固定数量的项目。因此,当一个新项目可能从底部进入时,以前的项目将从顶部消失。

因此 convertview 将是存储正在消失的数据的对象,您可以重新使用它来存储新的传入数据。

如果converView为null,则需要创建一个新视图来存储传入的数据。如果它不为空,您可以将它重新用于新数据而不是创建新视图。

  • 转换视图

这是一个之前膨胀过的视图(当 convertView==null 时)并且在屏幕上,但现在已经滚出屏幕,所以你可以重新使用它来显示视图中的数据即将进入画面

通过减少视图 inflation(对 inflater.inflate 的调用是昂贵的)来提高性能,减少垃圾收集,并减少内存分配。

  • 视图持有人

直接引用您的观点。

可能会提高性能,因为 findViewById 是一个围绕视图层次结构的 for 循环,它可能会占用 UI 线程相当宝贵的时间。这种改进可能很小,但在快速滚动列表中,每一纳秒都可以达到 60fps 的流畅度。