В настоящее время я пишу пользовательский BaseAdapter для ListView на Android. Список адаптер в основном работает хорошо, когда я первый вставки элементов в ListView, но при вставке новых элементов в середине, неправильные элементы отображаются после вызоваListView с расширенным базовым адаптером не обновляется должным образом
notifyDataSetChanged();
Вот упрощенный пример (ив раздели его вниз только необходимому, если я пропустил положить в какой-либо информации, пожалуйста, укажите комментарий):
public class FriendListAdapter extends BaseAdapter {
private ArrayList<SingleFriend> data;
private Activity activity = null;
private static int needAccept = -1;
private static int friend = -2;
private static int waiting = -3;
public FriendListAdapter(Activity a) {
this.activity = a;
data = new ArrayList<>();
}
public void AddFriend(SingleFriend newFriend, boolean silent) {
int insertInto = 0;
switch (newFriend.getFriendType()) {
case TYPE_FRIEND_WAIT_FOR_YOUR_ACCEPT:
insertInto = needAccept;
break;
case TYPE_FRIEND_WAIT_FOR_HIS_ACCEPT:
insertInto = waiting;
break;
case TYPE_FRIEND_ACCEPTED:
insertInto = friend;
break;
}
if (insertInto < 0) {
boolean found = false;
boolean inserted = false;
int index = 0;
do {
if (data.get(index).getFriendID() == insertInto) {
found = true;
} else if (found) {
if (data.get(index).getFriendID() < 0) {
data.add(index, newFriend);
inserted = true;
} else {
if (newFriend.getFriendName().compareToIgnoreCase(data.get(index).getFriendName()) < 0) {
data.add(index, newFriend);
inserted = true;
}
}
}
if (!inserted && index == data.size() - 1) {
data.add(newFriend);
inserted = true;
}
++index;
} while (index < data.size() && !inserted);
}
if (!silent) {
notifyDataSetChanged();
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (vi == null) {
LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
SingleFriend friend = (SingleFriend)getItem(position);
if (friend != null) {
switch (friend.getFriendType()) {
case TYPE_SEPARATOR:
vi = inflater.inflate(R.layout.friendlist_topic, null);
vi.setTag(friend);
((TextView)vi.findViewById(R.id.friendTopic)).setText(friend.getFriendName());
break;
case TYPE_FRIEND_ACCEPTED:
case TYPE_FRIEND_WAIT_FOR_HIS_ACCEPT:
case TYPE_FRIEND_WAIT_FOR_YOUR_ACCEPT:
// TODO: Community rating!
vi = inflater.inflate(R.layout.friendlist_item, null);
vi.setTag(friend);
((TextView)vi.findViewById(R.id.friendName)).setText(friend.getFriendName());
break;
default:
break;
}
}
}
return vi;
}
}
Почему отображаются неверные данные, после того, как список друзей вставляется в список друзей? Я что-то упускаю? Даже invalidate() не показывает правильные вещи (я знаю, invalidate - это плохая опция, а я только что сделал это для тестирования). Заранее спасибо!
Спасибо, я попробую это. И нет, никогда не будет скрытых данных, то, что будет вставлено, будет показано в списке. Но спасибо за эту информацию! Редактировать: Большое спасибо, проблема, на которую вы указали, была причиной моей ошибки. Чтобы избежать повторного раздувания просмотров после того, как что-то было вставлено, следует сохранить представление для каждого элемента, чтобы вернуть его в getView, и только надуть, если эта ссылка равна нулю или это будет плохо? – Nidhoegger
Да, но я вижу 'if (! Silent)' который вызывает 'notifyDataSetChanged'. Эта проверка не требуется, и notifyDataSetChanged следует вызывать каждый раз. В любом случае, я надеюсь, что это сработает для вас. – inmyth
Беззвучный вариант - это еще одна функция, которая вставляет в список друзей. Он вызывает себя notifyDataSetChanged после вставки более одного друга. Я хотел, чтобы список не обновлялся часто, когда это не было необходимо. – Nidhoegger