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