2012-01-12 104 views
1

我写了自定义的ContactListAdapter,它从ArrayAdapter扩展而来。我们假设列表只有三个元素。我打印getView()的每个调用中收到的View对象的位置和哈希码。我观察到视图对象没有正确返回。我在这里做错了什么?Android:getView()不返回正确的视图对象

private class ContactListAdapter extends ArrayAdapter<ContactItem> { 
... ... 
    @Override 
    public View getView(int aPosition, View aConvertView, ViewGroup aParent) { 
     Log.d(TAG, "Inside ContactListAdapter.getView()"); 
     if(aConvertView==null) { 
      Log.d(TAG, "ConvertView is null"); 
      // Inflate view... 
     } 
     Log.d(TAG, "Pos: " + aPosition + " View: " + aConvertView.hashCode()); 
     return aConvertView; 
    } 

这里是最初的视图创建日志:

D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): ConvertView is null 
D/ContactsActivity( 759): Pos: 0 View: 1156974184 
D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): ConvertView is null 
D/ContactsActivity( 759): Pos: 1 View: 1157007416 
D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): ConvertView is null 
D/ContactsActivity( 759): Pos: 2 View: 1157027832 

,当我点击第三个要素列表中的日志(请注意如何第一和最后一个元素的哈希码交换)。我的onClick方法只是使少数单位在各自的列表条目:

D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): Pos: 0 View: 1157027832 
D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): Pos: 1 View: 1157007416 
D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): Pos: 2 View: 1156974184 

,当我点击第二元素日志:

D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): Pos: 0 View: 1156974184 
D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): Pos: 1 View: 1157007416 
D/ContactsActivity( 759): Inside ContactListAdapter.getView() 
D/ContactsActivity( 759): Pos: 2 View: 1157027832 

这是反复观察,只有第一和最后一个条目的哈希码是每次交换。什么可能导致这种情况?

+0

我猜这是用于ListView?如果是这种情况,那么'ListView'回收现有视图 - 这就是'convertView'的用途。如果'convertView'不是'null',那么你需要用它来返回你的新'View'。 – Squonk 2012-01-12 08:52:46

+0

是的,这是Listview。好的...这很棘手。这意味着,每次调用getView()时都应该调用setTag()。我只在convertView为空时才这样做!我想这是错误的。 – nayan 2012-01-12 09:03:49

回答

3

convertView用于重新使用适配器视图的视图,因此当您显示列表并假设您的屏幕一次可以显示5行时,则对于创建5行视图convertView将保持为null,但是当您滚动你的适配器为你的适配器视图创建了新的视图,所以,在列表中的第六个元素在位置1重用视图。

+0

如果是这种情况,ViewHolder成语如何工作。例如,如果我想使用setTag()在视图中存储每个元素的单独数据。 – nayan 2012-01-12 08:59:17

+0

通过ViewHolder我们可以在适配器视图中获得视图的对象,并为每个视图设置新的值,因此它看起来像两行都使用不同的视图。 – jeet 2012-01-12 09:02:48

相关问题