Strangely enough my CustomBaseAdapter
is returning wrong position for the item that needs to be inflated and so on the adapter takes the wrong kind of data to display on the row!
Although i am using the ViewHolder
pattern, my ListView layout_height
is set to match_parent
and every possible way i have found, to ensure ListView items stability, is already implemented, the CustomBaseAdapter
seems not to be responding at it.
getView() method
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
mItemView = convertView;
if (convertView == null) {
mItemView = mInflater.inflate(R.layout.layout_listview_row, parent, false);
holder = new ViewHolder();
//setting up the Views
mItemView.setTag(holder);
} else {
holder = (ViewHolder) mItemView.getTag();
}
//Getting the item
final MyItem item = getItem(position);
//Doing some checks on my item and then display the appropriate data.
//By saying checks i mean something like:
if(item.getSomething().equals("blabla")){
//Load some pic
}else{
//Load another pic
}
//Now when i have scrolled the list once and return back to top,
//Suddenly in Logcat i am seeing that the first row is getting matched to
//the object in the 4th position, but it doesnt display its data. It displays
//the text from the first item as it was supposed to do. But the relation between
//the first row and the item's position is like 0->4.
}
Other methods
@Override
public int getCount() {
return this.mObjects.size();
}
@Override
public MyItem getItem(int position) {
return this.mObjects.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
I have literally searched and tried everything on Google! Nothing seems to have given me a solution.
Any help would be appreciated! Let me know if you need any more part of code.
You are "recycling" the display objects, but you are responsible for getting the proper data into them. The issue is this line of code:
mItemView = convertView;
convertView
is the "container" for your data. If convertView
is not null, then the container is constructed, but you must then put the appropriate data into it. This is typically done by "using" the position indicator.
Maybe like this:
if (convertView == null) {
mItemView = mInflater.inflate(R.layout.layout_listview_row, parent, false);
holder = new ViewHolder();
//setting up the Views
mItemView.setTag(holder);
} else {
holder = getItem(position);
mItemView.setTag(holder);
}
I suspect that mItemView
is the culprit here. Judging by the name, this is an instance field, so if more than one thread calls getView()
in your CustomBaseAdapter
, then mItemView
may change which recycled view it is pointing at right under your nose. Also, I assume that getView()
ends with a return mItemView
, right?
Anyway, I would advise to try eliminating mItemView
and just write the function like this:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.layout_listview_row, parent, false);
ViewHolder holder = new ViewHolder();
//setting up the Views
convertView.setTag(holder);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
// ...
return convertView;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With