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>,可根據攜帶內容作判斷跳轉不同分支,請根據實際業務邏輯自行拓展。



 

 

 

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