My listview reorders when I scroll through it..this is very confusing.
Here’s the custom adapter I’m using:
public class LoadExpenseList extends BaseAdapter{
List<Expense> expenses;
Context context;
public LoadExpenseList(Context context, int textViewResourceId,
List<Expense> expenses) {
super();
this.expenses = expenses;
this.context = context;
}
public View getView(final int position, View convertView, ViewGroup parent){
//View v = convertView;
AvailableExpenseView btv;
if (convertView == null) {
btv = new AvailableExpenseView(context, expenses.get(position));
} else {
btv = (AvailableExpenseView) convertView;
}
btv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.i("Expense_Availables", "Item Selected!!");
Intent intent = new Intent(getActivity(), ItemDetailActivity.class);
int id = expenses.get(position).getExpenseItemId();
intent.putExtra("id", id);
startActivity(intent);
}
});
btv.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View arg0) {
// TODO Auto-generated method stub
return false;
}
});
registerForContextMenu(btv);
return btv;
}
@Override
public int getCount() {
return expenses.size();
}
@Override
public Object getItem(int position) {
return expenses.get(position);
}
@Override
public long getItemId(int position) {
return expenses.get(position).getExpenseItemId();
}
}
Because your view (
AvailableExpenseView) is constructed with an item, then when the adapter tries to reuse views through convertView, you get a view that is already tied to another item.Don’t construct your view with your model item, instead call something like
convertView.setExpense(expenses.get(position)).ListView will try to reuse views to improve performance. So what will happen is that the first items in the list are displayed with newly created views and later on as you scroll it will try to reuse views previously created giving you the view through
convertView. Notice these lines:If convertView is null you are creating a new view, but you are constructing your view with an item. So let’s say this get called with position 0. You create a view using the expense which is first at the list. Later on, listView wants to get the view for let’s say position 20, and says “ok lets reuse the view that we used for position 0”, so it passes this view as
convertViewbut this view was already created with the item in position 0 and you don’t override this. So you end up using a view that has the first item to represent the 20th item.To solve this you can easily do something like this:
Of course you will have to edit
AvailableExpenseViewand create asetExpense()method to populate your view.