在自定义adapter
中,如何知道我是否需要重新配置convertView
?
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = (ImageView) mInflater.inflate(R.layout.avatar, parent, false);
// Should this 2 lines of code be here ?
User user = mUserList.getUserAt(position);
user.setAvatar(imageView);
} else {
imageView = (ImageView) convertView;
}
// or here ?
User user = mUserList.getUserAt(position);
user.setAvatar(imageView);
return imageView;
}
我认为如果它被回收,我不需要重置用户的头像,但我经常看到配置发生在if
块之外。那是为什么?
答案 0 :(得分:2)
我总是在if
块之外配置视图。您在getView方法中获得的这个convertView可能(并且很可能会)通过之前的getView调用为另一个用户设置,因为ListView的策略是在屏幕外重用项目视图。如果你没有设置一个合适的头像,那么这个项目就会出错。当然,您不需要重置与背景等具体位置无关的属性。
例如CursorAdapter separates getView分为两部分:newView,执行膨胀和(主要)位置无关设置,bindView分配实际位置相关数据。
也可能会出现与之前用于此位置的视图完全相同的视图。当然,在这种情况下,您可以避免重置视图,但需要检查此视图中的数据是否有效。我认为设置然后检查View tag是一个最明显的解决方案。
答案 1 :(得分:2)
它不是真正的回收,它只是意味着你需要根据新的位置用新数据填充“再循环”视图。如果你不这样做,那么这一行将填充旧的数据,这些数据在你滚动它的位置后不再在屏幕上可见。
因此,总之,每次调用getView()时,都必须使用新数据重新配置视图(在代码中if
块之外)。
答案 2 :(得分:1)
您的问题仅限于对listview的理解。
所以在这里我会告诉你它是如何工作的?
假设列表视图必须包含 20个项目,但您当前的屏幕只能容纳(在屏幕上显示) 8个项目(列出项目,在您的案例中为imageview)。< / p>
当listview尝试获取1----8th
的项目时,它会将convertView
作为null
返回给您,因为尚未回收对象。
但是,当你尝试滚动时,在我们的情况下(向上滚动!)。
the 1st element of the list will be recycled when go out of screen, and will be supplied as convertView for 9th item.
这样,listview必须只管理第8个(在我们的例子中)以显示任意数量的项目。
如果我们向下滚动病房,则会发生相反的情况。
因此,在转化视图的基础上(无论是否为空),您必须设计逻辑以创建和填充或填充。
希望这会对你有所帮助。