Это вопрос о внутреннем поведении RecyclerView для тех, кто знает свою механику или готов копать исходный код. Идентификатор как ответ, подкрепленный ссылками на источник.
Оригинальный вопрос
(прокрутите вниз до "Другими словами, для более сфокусированного вопроса)
Мне нужно понять, как действия notify*
(например, notifyItemInserted()
) помещаются в очередь. Представьте, что у меня есть адаптер, поддерживаемый этим списком:
ArrayList<String> list = Arrays.asList("one", "three", "four");
Я хочу добавить значения zero
и two
, которые отсутствуют.
Пример 1
list.add(1, "two");
// notify the view
adapter.notifyItemInserted(1);
// Seconds later, I go on with zero
list.add(0, "zero");
// notify the view
adapter.notifyItemInserted(0);
Это довольно прямолинейно и понятно, нечего сказать.
Пример 2
Но что, если два действия очень близки друг к другу, а между ними нет макета?
list.add(1, "two");
list.add(0, "zero");
Что мне теперь делать?
adapter.notifyItemInserted(1);
adapter.notifyItemInserted(0);
Или, может быть,
adapter.notifyItemInserted(2);
adapter.notifyItemInserted(0);
? С точки зрения адаптера список сразу переключается с one, three, four
на zero, one, two, three, four
, поэтому второй вариант кажется более разумным.
Пример 3
list.add(0, "zero");
adapter.notifyItemInserted(0);
list.add(2, "two");
adapter.notifyItemInserted(...)
Как насчет этого сейчас? 1
или 2
? Список сразу обновлялся, но я уверен, что между ними не было промежуточного макета.
Вопрос
У вас есть главная проблема, и я хочу знать, как я должен себя вести в этих ситуациях. Реальный случай заключается в том, что у меня есть несколько асинхронных задач, заканчивающихся методом insert()
. Я могу выполнить их операции, но:
- Я не хочу этого делать, если theres уже внутренняя очередь, и там, конечно,
- Я не знаю, что произойдет, если два действия не пройдут без макета, см. пример 3.
Другими словами
Чтобы обновить утилиту, необходимо выполнить 4 действия:
- Я фактически изменяю модель данных (например, вставляю что-то в массив подстановки)
- Я вызываю
adapter.notify*()
- Recycler получает вызов
- Recycler выполняет действие (например, вызывает
getItem*()
иonBind()
на адаптере) и излагает изменение.
Его легко понять, когда theres no concurrency, и они происходят последовательно:
1. => 2. => 3. => 4. => (new update) 1. => 2. => 3. => 4. ...
Давайте посмотрим, что происходит между шагами.
- Между 1. и 2.. Я бы сказал, что разработчик должен немедленно вызвать notify() после изменения данных. Это нормально.
- Между 2. и 3.. Это происходит немедленно, здесь нет проблем.
- Между 3. и 4.. Это происходит не. НАСКОЛЬКО МНЕ ИЗВЕСТНО. Поэтому вполне возможно, что новое обновление (шаги 1 и 2) происходит между шагами 3 и 4 предыдущего обновления.
Я хочу понять, что происходит в этом случае. Как мы должны себя вести? Должен ли я гарантировать, что предыдущий шаг 4 произошел, прежде чем вставлять новые вещи? Если да, то как?