Я хочу, чтобы мой 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