我在android中自定义创建的CursorAdapter派生类有一个奇怪的问题:
我的getView()实现是在许多网站/ Google会谈中看到的直接教科书。但是,似乎对于不同的位置(这个方法被调用的位置参数),这个方法正在传递 convertView 的相同实例,即使我看到它,这些应该引用不同的对象实例,因为它应该对应于ListView中的其他可见项,并且在可见列表项的情况下不应该重用相同的对象实例...
我删除了更新实际视图的实际部分,因为即使没有它也会重现问题。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
Log.d("dd", "getView()");
if (convertView == null) {
Log.d("d", "convertview is null!");
// create convertView from xml
convertView = this.mInflater.inflate(R.layout.catalog_entry,
parent, false);
// create the viewHolder
viewHolder = new ViewHolder();
viewHolder.name = (TextView) convertView
.findViewById(R.id.gameName2);
viewHolder.image = (ImageView) convertView
.findViewById(R.id.gameImage);
convertView.setTag(viewHolder);
} else {
Log.d("dd", "convertview is not null");
viewHolder = (ViewHolder) convertView.getTag();
}
LinearLayout thisItem = (LinearLayout) convertView;
Log.d("thisItem",
"This Item is Index "
+ position
+ " "
+ thisItem.toString()
+ " "
+ Integer.toHexString(System.identityHashCode(thisItem))
+ "x: " + thisItem.getX() + " y: " + thisItem.getY());
this.cur.moveToPosition((int) (getItemId(position) - 1));
Log.d("dd", "End of getView()");
return convertView;
}
运行此代码会产生以下输出:
D / dd(27725):getView()D / d(27725):convertview为null! D / thisItem(27725):此项目为索引0 android.widget.LinearLayout@40fb5f70 40fb5f70x:0.0 y:0.0 D / dd
(27725):getView()的结束D / dd(27725):getView()D / dd
(27725):convertview不为空D / thisItem(27725):此项目为索引 1 android.widget.LinearLayout@40fb5f70 40fb5f70x:0.0 y:0.0 D / dd
(27725):getView()的结束D / dd(27725):getView()D / dd
(27725):convertview不为空D / thisItem(27725):此项目为索引 2 android.widget.LinearLayout@40fb5f70 40fb5f70x:0.0 y:0.0 D / dd
(27725):getView()的结束D / dd(27725):getView()D / dd
(27725):convertview不为空D / thisItem(27725):此项目为索引 3 android.widget.LinearLayout@40fb5f70 40fb5f70x:0.0 y:0.0 D / dd
(27725):getView()的结束D / dd(27725):getView()D / dd
(27725):convertview不为空D / thisItem(27725):此项目为索引 4 android.widget.LinearLayout@40fb5f70 40fb5f70x:0.0 y:0.0 D / dd
(27725):getView()的结束D / dd(27725):getView()D / dd
(27725):convertview不为空D / thisItem(27725):此项目为索引 0 android.widget.LinearLayout@40fb5f70 40fb5f70x:0.0 y:0.0 D / dd
(27725):getView()结束D / dd(27725):getView()D / d
(27725):convertview为null! D / thisItem(27725):此项目为索引1 android.widget.LinearLayout@40fb89f8 40fb89f8x:0.0 y:0.0 D / dd
(27725):getView()结束D / dd(27725):getView()D / d
(27725):convertview为null! D / thisItem(27725):此项目为索引2 android.widget.LinearLayout@40fb9c48 40fb9c48x:0.0 y:0.0 D / dd
(27725):getView()结束D / dd(27725):getView()D / d
(27725):convertview为null! D / thisItem(27725):此项目为索引3 android.widget.LinearLayout@40fbae98 40fbae98x:0.0 y:0.0 D / dd
(27725):getView()结束D / dd(27725):getView()D / d
(27725):convertview为null! D / thisItem(27725):此项目为索引4 android.widget.LinearLayout@40fbc0e8 40fbc0e8x:0.0 y:0.0 D / dd
(27725):getView()的结束
从一开始就可以看出,对于每个位置(0到4),都会发送相同的View对象哈希......
答案 0 :(得分:4)
简而言之,将ListView的高度设置为match_parent
或其他固定高度。
ListView以“干运行”方式调用getView()
的原因有很多,最常见的是因为您使用了wrap_content
作为ListView的高度。 Android必须为一堆行充气以计算wrap_content
的高度,但它不能使用真实数据,因为它尚不可用。因此,适配器会抛出这些最佳猜测。稍后,使用实际数据(重新)创建布局,这就是为什么您看到每行创建两次。
CursorAdapter也应该自己维护相应的行,你不需要这一行:
this.cur.moveToPosition((int)(getItemId(position) - 1));
答案 1 :(得分:1)
Convertview
重用视图是正确的。
您可以删除所有Convertview
部分,并确保它不会重复使用不需要的视图,您将获得所需的结果(以某些性能为代价......)。