谁能解释一下 convertView 和 View Holder 模式在 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;
}
}
- 转换视图
这是一个以前膨胀的视图(当convertView==null
时(并且在屏幕上,但现在已滚动出屏幕,因此您可以重复使用它来显示即将进入屏幕的视图中的数据。
通过减少视图膨胀(对inflater.inflate
的调用成本高昂(来提高性能,减少垃圾回收,并减少内存分配。
- 视图持有人
保留对视图的直接引用。
可能会提高性能,因为findViewById
是一个围绕视图层次结构的 for 循环,可能会占用 UI 线程的宝贵时间。这种改进可能很小,但在快速滚动列表中,每一纳秒都算得上有一个不错的 60fps。
SO中有很多关于此的帖子。但简而言之,它是关于重用 ListView 中的对象,而不是实例化新对象。在列表视图中,屏幕上有固定数量的项目。因此,当一个新项目可能从底部进入时,前一个项目将从顶部消失。
因此,转换视图将是存储正在消失的数据的对象,您可以重复使用它来存储新的传入数据。
如果 converView 为空,则需要创建一个新视图来存储传入的数据。如果它不为 null,则可以将其重用于新数据,而不是创建新视图。