Как заставить 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