notifyItemChanged调用onCreateViewHolder

问题描述

我的recyclerView适配器有一个奇怪的问题,我只想根据选择显示/隐藏ImageView,但是当我在点击监听器中调用notifyItemChanged(selection)时,它会调用onCreateViewHolder并接受延迟刷新视图,我不知道为什么,也没有找到其他解决方案来执行所需的操作。

这是我的适配器:

public class ChannelAdapter extends RecyclerView.Adapter<ChannelAdapter.ChannelHolder> {
    private ArrayList<Integer> channelList;
    private Integer selection = 0;

    public ChannelAdapter(ArrayList<Integer> channelList) {
        this.channelList = channelList;
    }

    @NotNull
    @Override
    public ChannelHolder onCreateViewHolder(ViewGroup parent,int viewType) {
        Log.d(TAG,"onCreateViewHolder: ");
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_channel_item_selected,parent,false);
        ChannelHolder holder = new ChannelHolder(view);
        return holder;
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(ChannelHolder holder,int position) {
        Log.d(TAG,"onBindViewHolder: "+position);
        holder.textViewChannelId.setText("#"+channelList.get(position));
        holder.textViewChannel.setText(channelList.get(position).toString());

        if(position==selection){
            holder.imageViewSelectorLeft.setVisibility(View.VISIBLE);
            holder.imageViewSelectorRight.setVisibility(View.VISIBLE);
        }
        else{
            holder.imageViewSelectorLeft.setVisibility(View.INVISIBLE);
            holder.imageViewSelectorRight.setVisibility(View.INVISIBLE);
        }
    }

    @Override
    public int getItemCount() {
        return channelList.size();
    }

    public class ChannelHolder extends RecyclerView.ViewHolder {
        TextView textViewChannel,textViewChannelId;
        ImageView imageViewSelectorLeft,imageViewSelectorRight;

        public ChannelHolder(View itemView) {
            super(itemView);
            textViewChannelId = itemView.findViewById(R.id.textViewChannelId);
            textViewChannel = itemView.findViewById(R.id.textViewChannel);
            imageViewSelectorLeft = itemView.findViewById(R.id.imageViewSelectorLeft);
            imageViewSelectorRight = itemView.findViewById(R.id.imageViewSelectorRight);

            itemView.setonClickListener(v -> {
                notifyItemChanged(selection);
                selection=getAdapterPosition();
                notifyItemChanged(selection);
            });
        }
    }
}

我想念某件事还是做错了吗? 预先感谢您的帮助

编辑: 我尝试使用有效载荷设置为1的notifyItemChanged并覆盖onBindViewHolder来获得有效载荷,但是即使onCreateViewHolder设置为false

,它仍然调用mSupportsChangeAnimations >

解决方法

您可以像这样呼叫适配器

YourAdapter adapter = new YourAdapter(yourList,yourActivity.this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();

然后您可以将此代码放在适配器中的itemClick上

if(position==getAdapterPosition()){
        holder.imageViewSelectorLeft.setVisibility(View.VISIBLE);
        holder.imageViewSelectorRight.setVisibility(View.VISIBLE);
    }
    else{
        holder.imageViewSelectorLeft.setVisibility(View.INVISIBLE);
        holder.imageViewSelectorRight.setVisibility(View.INVISIBLE);
    }
,

默认情况下,您的RecyclerView将附加一个DefaultItemAnimator。当您在适配器上调用notifyItemChanged()时,系统最终将调用DefaultItemAnimator来查找是否需要创建新的ViewHolder或是否可以“重用”现有的。

@Override
public boolean canReuseUpdatedViewHolder(@NonNull ViewHolder viewHolder,@NonNull List<Object> payloads) {
    return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder,payloads);
}

超类实现:

@Override
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
    return !mSupportsChangeAnimations || viewHolder.isInvalid();
}

这些建议有两种简单的方法来确保重用ViewHolder而不是重新创建它们:

  • 确保payloads列表不为空。这是通过调用adapter.notifyItemChanged(position,payload)完成的。只要payload是非null,就无关紧要。
  • mSupportsChangeAnimations的{​​{1}}设置为false
DefaultItemAnimator

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...