Я хочу, чтобы мой RecyclerView не перерабатывал некоторые элементы

Я использую RecyclerView с неоднородными взглядами внутри, как видно из этого урока.

У меня есть некоторые элементы внутри этого RecyclerView, которые тоже являются RecyclerViews. Слишком сложно представить? Допустим, я хочу скопировать макет Play Store: один большой RecyclerView с вертикальной линейной компоновкой и заполненный множеством элементов: отдельные приложения и карусель приложений.

Если добавляемый элемент является макетом для одного приложения, то будет использоваться идентификатор 1, и я добавлю макет для одного элемента. Иначе, если мне нужно добавить карусель, я добавлю один элемент в основной RecyclerView: другой RecyclerView со своим собственным адаптером.

Это работает очень хорошо. За исключением случаев прокрутки основного RecyclerView. Зачем? Потому что некоторые виды разрушаются, когда больше не видны, а затем воссоздаются в onBindViewHolder() метод. Почему здесь? Поскольку адаптер основного RecyclerView проходит для позиции X, а затем вызывает OnBindViewHolder(), Затем последний создает новый RecyclerView со своим собственным адаптером и назначает его ему. Я хотел бы сохранить эти взгляды только потому, что их тяжело каждый раз перекачивать.

Это возможно? Если так, можете ли вы сказать мне, как?

8 ответов

Решение

Использовать этот:

recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_CAROUSEL, 0);

Это не будет перерабатывать любое представление viewType TYPE_CAROUSEL но если количество элементов этого типа очень велико, то это значительно снизит вашу производительность, возможно, даже вызовет OOME

РЕДАКТИРОВАТЬ

Прочитав ответ MML13, я думаю, что он может сработать для вас. Вы беспокоитесь о том, что элементы вашей карусели будут повторно накачаны, когда это представление будет перебазировано во внешнем RecyclerView. Если все эти карусели имеют одинаковый тип, то есть все они используют один и тот же адаптер, вы можете оставить адаптер внутри внешнего ViewHolder RecyclerView и просто поменять данные и вызвать notifyDataSetChanged() или же notifyItemRangeChanged(...) на этом адаптере, когда он перевязан. Это перезапустит все виды карусели и все виды внутри этих каруселей.

Вы также можете установить приведенный ниже код в методе адаптера onBindViewholder().

holder.setIsRecyclable(false);

Я взял ссылку по этой ссылке

http://aphoe.com/blog/prevent-androids-recyclerview-recycling-views/

Вы можете добавить в свой адаптер:

@Override
public void onBindViewHolder(final CommentViewHolder viewHolder, final int position) {
    viewHolder.setIsRecyclable(false);
}

Информирует переработчика, может ли этот предмет быть переработан. Виды, которые не подлежат вторичной переработке, не будут повторно использоваться для других элементов, пока setIsRecyclable() позже установлено в true. Звонки в setIsRecyclable() всегда должен быть в паре (один вызов setIsRecyclabe(false) всегда должны быть сопоставлены с последующим вызовом setIsRecyclable(true)). Пары вызовов могут быть вложенными, так как состояние внутренне подсчитывается.

Потому что некоторые представления уничтожаются, когда они больше не видны, а затем воссоздаются в методе onBindViewHolder().

Это неправда, они не создаются снова, они просто переплетаются. если у вас есть вид на позицию X (в лом или переработчик) RecyclerView собирается использовать это и связать это.

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

Главный RecyclerView держит их для вас. Вам нужно только изменить данные адаптера вашего второго RecyclerView и позвонить notifyDataSetChanged, Также храните свой второй RecyclerView адаптер внутри viewHolder вашего основного RecyclerView,

Установите ниже строку в вашей деятельности

recyclerView.getRecycledViewPool().setMaxRecycledViews(1,0);

установить код ниже в классе RecyclerViewAdapter

@Override
    public int getItemViewType(int position) {
        return 1;
    }

Мой код работает для сброса пользовательского интерфейса в recycleview.

public class BooleanViewHolder extends BaseViewHolder<ConfigItemBoolean> {
    private SwitchCompat configBoolean;

    BooleanViewHolder(View view) {
        super(view);
        configBoolean = view.findViewById(R.id.enable_config_boolean);
        configBoolean.setOnCheckedChangeListener((buttonView, isChecked) -> {
            ((ConfigItemBoolean) getItem(getAdapterPosition())).setValue(isChecked);
            DataSet.mConfigDataSet.getConfigItemBooleanMap().put(configPairList.get(getAdapterPosition()).first, ((ConfigItemBoolean) getItem(getAdapterPosition())));
        });
    }

    @Override
    void bind(ConfigItemBoolean item, String key) {
        configBoolean.setText(item.getDisplayName());
        configBoolean.setChecked(item.isValue());
    }

}

Единственное решение, которое сработало для меня, было:

      recyclerView.setItemViewCacheSize(INT)
recyclerView.setDrawingCacheEnabled(true)

В этом случае элементы RecyclerView не будут переработаны, но их можно будет заменить или удалить.

попробуй это

      recyclerView.getRecycledViewPool().setMaxRecycledViews(youViewHolder type,0);

если вы используете viewHolder.setIsRecyclable(false); будет происходить несколько одинаковых просмотрщиков в recyclerview

Другие вопросы по тегам