Как заставить RecyclerView перестать перерабатывать определенные позиции?
Моя проблема: у меня потоковое видео происходит на одном из видов внутри RecyclerView.
Когда пользователь прокручивается, просмотр становится переработанным, а другие камеры запускают собственную поточную передачу на этом переработанном объекте просмотра. Это плохо для пользовательского интерфейса, так как для потокового процесса требуется несколько секунд.
Как я могу сказать RecyclerView: "Эй, ресайклеров, пожалуйста, не перерабатывайте эту точную позицию x и дайте этой позиции ВСЕГДА того же самого зрителя, которого вы дали в первый раз, вместо случайного"?
Пожалуйста, помогите мне = (
Ответы
Ответ 1
В вашем адаптере getItemViewType(int position)
присваивайте уникальные значения для каждого видео, поэтому он всегда будет возвращать тот же ViewHolder для того же видео, что и вы.
- возвращает уникальный положительный номер как тип для каждого типа видео (здесь я использовал позицию адаптера как уникальный ключ)
- вернуть отрицательные числа для любых элементов, не относящихся к видео. (здесь ничего особенного, просто чтобы избежать конфликтов с видеоматериалами, мы используем отрицательные числа для элементов, не относящихся к видео).
Надеюсь, ты получишь эту идею. приветствия:)
@Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
if(dataList.get(position).isVideo()){
return position;
}else{
return -1;//indicates general type, if you have more types other than video, you can use -1,-2,-3 and so on.
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case -1: View view1 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.general_item, parent, false);
return new GeneralViewHolder(view1);
default:View view2 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_item, parent, false);
return new VideoViewHolder(view2);
}
}
Ответ 2
Выполните viewHolder.setIsRecyclable(false)
в ViewHolder
, который вы хотите перегрузить не.
Из docs ViewHolder # setIsRecyclable (boolean):
Сообщает переработчику, может ли этот элемент перерабатываться. Представления, которые не подлежат вторичной переработке, не будут использоваться повторно для других элементов, пока setIsRecyclable() не будет установлен в значение true.
Это приведет к созданию только одного ViewHolder
.
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...
@Override
public void onViewAttachedToWindow(final RecyclerView.ViewHolder holder) {
if (holder instanceof VideoViewHolder) {
holder.setIsRecyclable(false);
}
super.onViewAttachedToWindow(holder);
}
@Override
public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder) {
if (holder instanceof VideoViewHolder){
holder.setIsRecyclable(true);
}
super.onViewDetachedFromWindow(holder);
}
...
}
Ответ 3
Ваша проблема исходит от самого зрителя. У зрителей есть ссылка на представления, в то время как адаптер нет. Адаптер сохраняет только сбор данных. Таким образом, добавьте поле к наблюдателю, чтобы сохранить ссылку на элемент данных, который вы использовали для заполнения представления в узле просмотра. Другими словами:
public class SomeViewHolder extends RecyclerView.ViewHolder{
private View view;
private Data data;
public SomeViewHolder(View itemView) {
super(itemView);
view = itemView;
}
public void bindData(Data data){
view.setData(data);
this.data = data;
}
public void setData(Data data){
this.data = data;
}
public Data getData(){
return data;
}
public View getView(){
return view;
}
}
Теперь зритель знает, какой элемент адаптера использует. Поэтому, переопределяя метод привязки в адаптере, вы можете проверить, уже ли держатель связан с некоторыми данными, и, если данные содержат видео, вы можете избежать привязки и принудительно установить уже загруженное представление.
@Override
public void onBindViewHolder(SomeViewHolder holder, int position) {
//videoViewData is a data field you have to put into the adapter.
//videoView is a view field you have to put into the adapter.
if(adapterData.get(position).equals(videoViewData)){
holder.setView(videoView);
holder.setData(adapterData.get(position));
}else{
holder.bindData(adapterData.get(position));
if(adapterData.get(position).isVideo()){
videoViewData = adapterData.get(position);
videoView = holder.getView();
}
}
}
Наконец, вам придется переопределить метод onViewRecycled в адаптере, поэтому, когда просмотр, содержащий видео, перерабатывается, вы можете получить представление и поместить его в другое место.
public void onViewRecycled(SomeViewHolder holder){
if(holder.getData().isVideo()){
videoViewData = holder.getData().
videoView = holder.getView();
videoView.pauseVideo();
}
}
помните, что это может привести к серьезным утечкам, если вы не управляете сохраненным представлением. Кроме того, вы должны определить методы для сообщения, когда ваши данные являются видео, и правильно установленный метод equals.
Ответ 4
RecyclerView использует один вид несколько раз, когда он содержит список, который не отображается на экране за раз (означает, что список содержит большое количество элементов, которые не отображаются на экране в то же время, вам нужно прокручивать вверх и вниз). Когда пользователь просматривает список, элементы заставки повторно используются для отображения оставшихся элементов списка, которые называются рециркуляцией.
Чтобы остановить повторное использование элементов, вызовите этот метод в методе onBindViewHolder:
viewHolder.setIsRecyclable(false);
Этот оператор останавливает повторное использование представлений.
Чтобы начать повторное использование элементов, вызовите этот метод в методе onBindViewHolder:
viewHolder.setIsRecyclable(true);
Я надеюсь, что это решит вашу проблему.
Благодаря
Ответ 5
Попробуйте использовать это для этой конкретной позиции:
holder.setIsRecyclable(false);
Надеюсь, это поможет.
Ответ 6
Лучший способ справиться с предметом, не предназначенным для повторного использования в утилизации. Посмотрите этот ответ, чтобы решить вашу проблему.
Не перерабатывать товар
Ответ 7
Если вы используете запрос, вы можете использовать
query.limit(//no of items you want to show in your RecyclerView)
попробуйте.
или Plese разместите свой QueryCode