RecyclerView - после удаления двух элементов из списка, а потом добавления их обратно, они накладываются друг на друга

Рейтинг: -1Ответов: 2Опубликовано: 20.08.2023

Есть RecyclerView, находящийся внутри алертдиалога. В нулевой позиции расположен item со свичом. Если свич вкл., то надо показать ещё два элемента под ним, а если выкл., то убрать эти элементы.

Беда в том, что если убрать элементы из списка, а потом снова добавить, то появляются их версии, которые были до удаления + свежедобавленные элементы прямо поверх них.

Все вьюшки создаются программно, без XML.

Вот код:

if (position == 0) {
                    MaterialSwitch switcher = DialogUtil.getRecyclerView().getLayoutManager().findViewByPosition(0).findViewWithTag("switch");

                    if (switcher.isChecked()) {

                        items.add(1, new RecyclerViewItem(RecyclerViewItem.OPTION_SNOOZE_SETTINGS_DURATION, getString(R.string.snooze_duration), 10, 5, 45, new LabelFormatter() {
                            @NonNull
                            @Override
                            public String getFormattedValue(float value) {
                                return getResources().getQuantityString(R.plurals.minutes, (int) value, (int) value);
                            }
                        }, true));
                        items.add(2, new RecyclerViewItem(RecyclerViewItem.OPTION_SNOOZE_SETTINGS_MAX_COUNT, getString(R.string.max_snoozes), 1, 1, 11, new LabelFormatter() {
                            @NonNull
                            @Override
                            public String getFormattedValue(float value) {

                                if (value != 11.0) {
                                    return getResources().getQuantityString(R.plurals.times, (int) value, (int) value);
                                } else {
                                    return getString(R.string.unlimited);
                                }
                            }
                        }, true));

                        DialogUtil.getRecyclerView().getAdapter().notifyItemRangeInserted(1, 2);
                    } else {
                        items.remove(2);
                        items.remove(1);

                        DialogUtil.getRecyclerView().getAdapter().notifyItemRangeRemoved(1, 2);
                    }
                }

Ответы

▲ 0

Так, ладно, решение я нашёл - добавил в ветку else условия switcher.isChecked() код удаения всех вьюшек из корневого лэйатуа item'a: `

 //Сначала удалим View из item'ов
                        ConstraintLayout layout1 = DialogUtil.getRecyclerView().getLayoutManager().findViewByPosition(1).findViewWithTag("rootLayout");
                        ConstraintLayout layout2 = DialogUtil.getRecyclerView().getLayoutManager().findViewByPosition(2).findViewWithTag("rootLayout");

                        layout1.removeAllViews();
                        layout2.removeAllViews();

Но мне всё равно не понятно, почему эти вьюшки остались, а не удалились после Adapter::notifyItemRangeRemoved()

▲ 0

Не нужно пытаться удалять элементы из списка по индексу через removeAllViews(). Попробуйте более детально узнать как работает RecyclerView, в частности адаптер. Адаптер принимает список элементов (в вашем случаи это айтемы со свитчами). Чтобы удалить какой-то из этих элементов просто предоставьте адаптеру новый список без этого элемента и вызывайте notifyDataSetChanged(). Так же вы говорили, что свитч у вас влияет на внешний вид айтема. Эту логику можно реализовать во ViewHolder, например если switcher.isChecked() просто сделайте view.show() или view.gone(). Тоесть те самые два элемента, которые показываются по свитчу пускай будут чайлдами конкретного айтема из списка.