Stack Overflow на русском Asked by DenVebber on December 9, 2021
Всем привет!
Есть RecyclerView, которым управляю через адаптер.
Несколько элементов добавляю так:
public void addItemsToList(ArrayList<Item> itemsList)
{
items.addAll(itemsList);
adapter.notifyDataSetChanged();
}
Один элемент добавляю так:
public void addCommentToList(Item item)
{
items.add(item);
adapter.notifyDataSetChanged();
}
Для списка прописана возможность множественного выбора элементов и их удаления. На клиенте пользователь выбирает элементы списка, их id отправляется на сервер и при успешном удалении из БД приход ответ.
Знаю, что удалить один элемент можно по его позиции и обновить отображение в адаптере так:
public void deleteItemFromList(int position)
{
items.remove(position);
adapter.notifyItemRemoved(position);
}
Нашёл вариант, когда удаляются несколько элементов, которые следуют друг за другом в списке (через номера позиций, например с 1 по 4), но он не подходит, потому что могут быть выбраны элементы из разных позиций, не идущие друг за другом.
Сейчас я сохраняю позиции элементов для удаления в ArrayList, а потом пытаюсь перебрать их:
public void deleteItemsFromList(ArrayList<Integer> positions)
{
for (int i = 0; i < positions.size(); i++)
{
items.remove(positions.get(i));
adapter.notifyItemRemoved(positions.get(i));
}
}
Но такой вариант работает некорректно (сначала удаляет элементы, а потом обновляет список и они снова появляются). Думаю, что должен быть какой-то универсальный способ такого удаления.
Вопрос в том, как правильно удалить сразу несколько элементов из списка и обновить его, если известны позиции для удаления?
Есть альтернативный способ решения проблемы.
Поскольку вы берете список из БД, то следует объявить адаптер как hasStableIds()
и в Item
завести id
равный первичному ключу БД (обычно Long
) откуда вы берете данные
Когда вы помечаете элемент на удаление создаете списочек ArrayList<Long> idsToRemove
, через adapter.getItemId(position)
Далее проходитесь по списку элементов idsToRemove
, спокойно все удаляете и вызываете notifyDataSetChanged()
Answered by Barmaley on December 9, 2021
Я бы сделал это так:
Создал бы в Adapter
метод вроде такого:
public void update(List<Item> items){
this.items.clear();
this.items.addAll();
notifyDataSetChanged(); //вот тут лучше использовать DiffUtils вместо этого метода
}
Весь список данных стоит держать где-то за пределами Adapter
, например Presenter/ViewModel
. Как только вы нажимаете "удалить N элементов" - вы передаете список этих элементов в ваш Presenter/ViewModel
, там удаляете их из списка и вызываете метод update()
адаптера с новыми данными.
Чтоб каждый раз не пересоздавать весь список используйте DiffUtils.
При таком подходе ваш адаптер будет уметь только отрисовывать элементы (соблюдается Принцип единой ответственности), и вы сможете легко изменять его содержимое в любом месте вашего кода.
Единственное, что вам придется решить как вы будете получать список удаляемых элементов.
Answered by Sergei Buvaka on December 9, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP