android - 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);
});
}
}
}
我错过了什么还是我做错了?提前感谢您的帮助
编辑:
我尝试使用notifyItemChanged
设置为 1 的有效负载并覆盖onBindViewHolder
以获取有效负载,但它仍然调用onCreateViewHolder
,即使mSupportsChangeAnimations
设置为 false
解决方案
默认情况下,您的 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
只要它是非空的,它是什么并不重要。 - 设置
mSupportsChangeAnimations
为false
您的DefaultItemAnimator
.
DefaultItemAnimator animator = (DefaultItemAnimator) recyclerView.getItemAnimator();
animator.setSupportsChangeAnimations(false);
推荐阅读
- python - 如何使用 flask-sqlalchemy 获得特定值?
- docker - 处理裸机中 kubernetese 上的暴露端口
- vba - Excel 加载项在具有选择更改事件的工作簿中不起作用
- javascript - 是否可以推迟 Javascript 中抛出的错误的执行?
- javascript - 在 OpenLiteSpee Web 服务器中托管 Angular 应用程序
- java - 回滚或重置 BufferedWriter
- angular - 使用 Angular HostBing 添加类而不擦除现有类
- debugging - 使用 Blackmagic probe 和 platformIO undefinedError 进行调试
- python - 如何在python中迭代列表中的项目?
- python - 基于python中元素出现的字符串裁剪