Поскольку ваше представление (AvailableExpenseView
) создается с элементом, то, когда адаптер пытается повторно использовать представления через convertView, вы получаете представление, которое уже связано с другим элементом.
Не конструироватьваше представление с вашим элементом модели, вместо этого вызовите что-то вроде convertView.setExpense(expenses.get(position))
.
ListView попытается повторно использовать представления для повышения производительности.Итак, что произойдет, так это то, что первые элементы в списке будут отображаться с вновь созданными представлениями, а позже при прокрутке будет пытаться повторно использовать ранее созданные представления, давая вам представление через convertView
.Обратите внимание на следующие строки:
if (convertView == null) {
// You create a view using the proper item
btv = new AvailableExpenseView(context, expenses.get(position));
} else {
// You don't override the item that was previously assigned
// when the view was created
btv = (AvailableExpenseView) convertView;
}
Если convertView имеет значение null, вы создаете новое представление, но вы создаете свое представление с помощью элемента.Допустим, это вызывается с позиции 0. Вы создаете представление, используя расходы, которые являются первыми в списке.Позже, listView хочет получить представление, скажем, для позиции 20, и говорит: «Хорошо, давайте снова используем представление, которое мы использовали для позиции 0», поэтому он передает это представление как convertView
, но это представление уже было создано с элементом впозиция 0, и вы не переопределите это.Таким образом, вы в конечном итоге используете представление, в котором первый элемент представляет 20-й элемент.
Чтобы решить эту проблему, вы можете легко сделать что-то вроде этого:
AvailableExpenseView btv;
if (convertView == null) {
// dont create your view with an item
btv = new AvailableExpenseView(context);
} else {
btv = (AvailableExpenseView) convertView;
}
// Assign the expense wether it is a newly created view or
// a view that is reused
btv.setExpense(expenses.get(position));
Конечно, вам придетсяотредактируйте AvailableExpenseView
и создайте метод setExpense()
, чтобы заполнить ваше представление.