I have a strange problem with a custom created CursorAdapter derived class in android:
My getView() implementation is straight textbook seen on many sites/Google talks. However, it seems that for different positions (position parameter that this method is called with), this method is being passed the same instance of convertView, even though as i see it, these should refer to different object instances, as it should correspond to other visible items in the ListView, and shouldn't reuse the same object instance in case of visible list items...
I have removed the actual part that updates the actual views since the issues reproduces even without it.
@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;
}
Running this code produces this output:
D/dd (27725): getView() D/d (27725): convertview is null! D/thisItem(27725): This Item is Index 0 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/dd
(27725): convertview is not null D/thisItem(27725): This Item is Index 1 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/dd
(27725): convertview is not null D/thisItem(27725): This Item is Index 2 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/dd
(27725): convertview is not null D/thisItem(27725): This Item is Index 3 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/dd
(27725): convertview is not null D/thisItem(27725): This Item is Index 4 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/dd
(27725): convertview is not null D/thisItem(27725): This Item is Index 0 android.widget.LinearLayout@40fb5f70 40fb5f70x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/d
(27725): convertview is null! D/thisItem(27725): This Item is Index 1 android.widget.LinearLayout@40fb89f8 40fb89f8x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/d
(27725): convertview is null! D/thisItem(27725): This Item is Index 2 android.widget.LinearLayout@40fb9c48 40fb9c48x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/d
(27725): convertview is null! D/thisItem(27725): This Item is Index 3 android.widget.LinearLayout@40fbae98 40fbae98x: 0.0 y: 0.0 D/dd
(27725): End of getView() D/dd (27725): getView() D/d
(27725): convertview is null! D/thisItem(27725): This Item is Index 4 android.widget.LinearLayout@40fbc0e8 40fbc0e8x: 0.0 y: 0.0 D/dd
(27725): End of getView()
It can be seen in the beginning that for each position (0 through 4), the same View object hash is being sent...
In short, set your ListView's height to match_parent
or another fixed height.
There are many reason that ListView calls getView()
in the "dry run" manner that you see, the most common is because you have used wrap_content
as the ListView's height. Android must inflate a bunch of rows to calculate the height for wrap_content
, but it cannot use real data since this isn't available yet. So the Adapter throws these best guesses out. Later the layout is (re)created with actual data, which is why you see the each row create twice.
Also a CursorAdapter should maintain the appropriate row itself, you don't need this line:
this.cur.moveToPosition((int)(getItemId(position) - 1));