在使用RecyclerView 的过程中,可以调用Adapter以下方法,实现视图刷新:
- notifyItemChanged(int position, @Nullable Object payload)
对指定位置的item重新布局显示
payload:可选参数,使用null时等同notifyItemChanged(int position)
- notifyItemChanged(int position)
对指定位置的item重新布局显示
- notifyDataSetChanged()
所有视图重新布局,重新显示
下面主要介绍前两个方法的区别。
payload参数作用
我们知道:一个item往往由许多控件组成,如Button、CheckBox、TextView、ImageView、EditText等组合。当我们点击item的某个控件时,RecyclerView需要重新计算布局、刷新视图来响应交互。假设一个item包含了N多个控件,如果调用notifyItemChanged(int position) 时,item中的每个控件都需要重新布局显示,无形中加大了内存和性能的损耗。
最常见的坑就是点击item的一个button,却引起同item的ImageView图片闪烁了一下。payload参数就是用于解决上述问题。
实现过程
1、点击事件调用:notifyItemChanged(int position, @Nullable Object payload)
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { adapter.notifyItemChanged(2, "aaaaa"); } }); 2、系统自动回调Adapter.onBindViewHolder(holder, position, List<Object> payloads)方法: public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> { @Override // 方法1 public void onBindViewHolder(@NonNull PayloadVHolder holder, int position, @NonNull List<Object> payloads) { if (payloads.isEmpty()) { onBindViewHolder(holder, position); } else { String payload = payloads.get(0).toString(); if ("aaaaa".equals(payload)) { holder.textView.setText("局部刷新结果:点击了位置-->" + position); } else if ("bbbbb".equals(payload)) { // 显示1秒后,取消高亮字体…… } else { } } } @Override // 方法2 public void onBindViewHolder(@NonNull PayloadVHolder holder, int position) { holder.textView.setText("初始化内容:" + datas.get(position)); holder.imageView.setImageResource(R.mipmap.ic_launcher); holder.button.setText("点击我试试); }
其中:
- 当RecyclerView 初始化显示时,也会执行方法1,但由于payloads为空,item下的所有控件都布局、计算、显示
- 当点击item传递了payload = “aaaaa”,在方法1 的payloads 可以得到它,payload不为空,说明不是首次显示,只更新ViewHolder下的 holder.textView 而不是全部子控件,这样就实现了局部刷新。具体请参照方法1、2的红色字体部分
- payloads是一个list<Object>,可根据携带内容作判断跳转不同分支,请根据实际业务逻辑自行拓展。