Android之RecyclerView巧用payload实现局部刷新

在使用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>,可根据携带内容作判断跳转不同分支,请根据实际业务逻辑自行拓展。



 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章