學(xué)習(xí)資料:
- 張旭童同學(xué)的Android 7.0帶來的新工具類:DiffUtil
十分感謝 :)
DiffUtil
是android.support:design:24.2.0
中推出的一個(gè)RecyclerView
的輔助工具類
作用:
當(dāng)Adapter
中的數(shù)據(jù)發(fā)生變化時(shí)派继,用來比較Adpater
中變化前和后兩個(gè)數(shù)據(jù)集合恩急,實(shí)現(xiàn)差異化更新拌蜘。而兩個(gè)集合的整個(gè)比較過程烤芦,以及針對(duì)數(shù)據(jù)變化該調(diào)用哪些notifyData
方法举娩,內(nèi)部會(huì)自動(dòng)進(jìn)行處理
1.簡(jiǎn)單使用 <p>
使用的步驟:
- 創(chuàng)建一個(gè)
DiffUtilCallback
繼承DiffUtil.Callback
,重寫里面的抽象方法 - 使用
DiffUtil.calculateDiff(callback)
构罗,計(jì)算差異結(jié)果铜涉,需要DiffUtilCallback
,返回對(duì)象為DiffUtil.DiffResult
遂唧。 - 使用
DiffResult
對(duì)象芙代,通過diffResult.dispatchUpdatesTo(adapter)
方法,將DiffUtil
與Adapter
關(guān)聯(lián)起來
大致的思路就是這個(gè)樣子盖彭,基本也是死套路
效果:
點(diǎn)擊RecyclerView
的一個(gè)item
,將學(xué)科全部改變召边,并在postion
為2
處铺呵,加入一個(gè)item
1.1 創(chuàng)建DiffUtilCallback
直接繼承DiffUtil.Callback
,之后Anddroid Studio
便會(huì)自動(dòng)提示必須要重寫4
個(gè)的方法
class DiffUtilCallback extends DiffUtil.Callback {
private List<ResourceBean> oldList = new ArrayList<>();
private List<ResourceBean> newList = new ArrayList<>();
public void setNewList(List<ResourceBean> newList) {
if (null != newList) {
this.newList.clear();
this.newList.addAll(newList);
}
}
public void setOldList(List<ResourceBean> oldList) {
if (null != oldList) {
this.oldList.clear();
this.oldList.addAll(oldList);
}
}
/**
* 數(shù)據(jù)變化之前隧熙,舊的數(shù)據(jù)集合size
*/
@Override
public int getOldListSize() {
Log.e("oldList.size", "---->" + oldList.size());
return oldList.size();
}
/**
* 數(shù)據(jù)變化之后片挂,新的數(shù)據(jù)集合size
*/
@Override
public int getNewListSize() {
Log.e("newList.size", "---->" + newList.size());
return newList.size();
}
/**
* 根據(jù)position來對(duì)新舊集合中的Object進(jìn)行判斷
*/
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
ResourceBean oldBean = oldList.get(oldItemPosition);
ResourceBean newBean = newList.get(newItemPosition);
Log.e("areItemsTheSame", oldItemPosition + "--" + newItemPosition + "---->" + oldBean.getSubject().equals(newBean.getSubject()));
return oldBean.getSubject().equals(newBean.getSubject());//比較科目
}
/**
* 根據(jù)position來對(duì)新舊集合中的Object的內(nèi)容進(jìn)行判斷
*/
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
ResourceBean oldBean = oldList.get(oldItemPosition);
ResourceBean newBean = newList.get(newItemPosition);
Log.e("areContentsTheSame", oldItemPosition + "--" + newItemPosition + "---->" + oldBean.getName().equals(newBean.getName()));
return oldBean.getName().equals(newBean.getName());//比較學(xué)科
}
/**
* 返回的特定的差異化結(jié)果
*/
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
ResourceBean oldBean = oldList.get(oldItemPosition);
ResourceBean newBean = newList.get(newItemPosition);
Bundle diffBundle = new Bundle();
if (!oldBean.getName().equals(newBean.getName())) {
diffBundle.putSerializable("newBean",newBean);
}
return diffBundle;
}
}
ResourceBean
內(nèi)只有兩個(gè)String
類型的subject,name
的set贞盯,get
方法宴卖,不再給出
1.2 Adapter代碼
適配器就是一個(gè)一般寫法的適配滋将,代碼比較簡(jiǎn)單
class PayloadAdapter extends RecyclerView.Adapter<PayloadAdapter.RecyclerHolder> {
private Context mContext;
private List<ResourceBean> dataList = new ArrayList<>();
private onRecyclerItemClickerListener mListener;
public PayloadAdapter(RecyclerView recyclerView) {
this.mContext = recyclerView.getContext();
}
/**
* 增加點(diǎn)擊監(jiān)聽
*/
public void setItemListener(onRecyclerItemClickerListener mListener) {
this.mListener = mListener;
}
/**
* 設(shè)置數(shù)據(jù)源
*/
public void setData(List<ResourceBean> dataList) {
if (null != dataList) {
this.dataList.clear();
this.dataList.addAll(dataList);
}
}
public List<ResourceBean> getDataList() {
return dataList;
}
@Override
public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout, parent, false);
return new RecyclerHolder(view);
}
@Override
public void onBindViewHolder(RecyclerHolder holder, int position) {
ResourceBean resourceBean = dataList.get(position);
holder.textView.setText(resourceBean.getSubject() + "--->" + resourceBean.getName());
holder.textView.setOnClickListener(getOnClickListener(position));
}
@Override
public void onBindViewHolder(RecyclerHolder holder, int position, List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
if (payloads.isEmpty()) {
Log.e("isEmpty", "---->" + payloads.isEmpty());
onBindViewHolder(holder, position);
}else {
Log.e("isEmpty", "---->no null");
Bundle bundle = (Bundle) payloads.get(0);
ResourceBean resourceBean = (ResourceBean) bundle.get("newBean");
if (null == resourceBean) return;
// Log.e("change", "---->" + change);
holder.textView.setText(resourceBean.getSubject() + "--->" + resourceBean.getName());
}
}
private View.OnClickListener getOnClickListener(final int position) {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener && null != v) {
mListener.onRecyclerItemClick(v, dataList.get(position), position);
}
}
};
}
@Override
public int getItemCount() {
return dataList.size();
}
class RecyclerHolder extends RecyclerView.ViewHolder {
TextView textView;
private RecyclerHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.tv__id_item_layout);
}
}
/**
* 點(diǎn)擊監(jiān)聽回調(diào)接口
*/
public interface onRecyclerItemClickerListener {
void onRecyclerItemClick(View view, Object data, int position);
}
}
加入了一個(gè)onBindViewHolder(RecyclerHolder holder, int position, List<Object> payloads)
方法
1.3 與Adapter進(jìn)行關(guān)聯(lián) <p>
在創(chuàng)建Adapter的Activity中,完整代碼:
class DiffUtil2Activity extends AppCompatActivity {
private RecyclerView rv;
private PayloadAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diff_util2);
init();
}
private void init() {
rv = (RecyclerView) findViewById(R.id.rv_diff2_util_activity);
//布局管理器
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
rv.setLayoutManager(manager);
//設(shè)置ItemDecoration
rv.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
//適配器
mAdapter = new PayloadAdapter(rv);
rv.setAdapter(mAdapter);
//添加數(shù)據(jù)
addData();
}
private void addData() {
DiffUtilCallback callback = new DiffUtilCallback();
callback.setOldList(mAdapter.getDataList());
List<ResourceBean> oldList = new ArrayList<>();
for (int i = 'A'; i < 'D'; i++) {
for (int j = 0; j < 15; j++) {
ResourceBean resourceBean = new ResourceBean();
resourceBean.setSubject("學(xué)科" + (char) i);
resourceBean.setName("資料" + j);
oldList.add(resourceBean);
}
}
callback.setNewList(oldList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);//子線程計(jì)算差異
diffResult.dispatchUpdatesTo(mAdapter);
//記得將新數(shù)據(jù)替換adapter中舊的集合數(shù)據(jù)
mAdapter.setData(oldList);
//設(shè)置點(diǎn)擊事件
mAdapter.setItemListener(new PayloadAdapter.onRecyclerItemClickerListener() {
@Override
public void onRecyclerItemClick(View view, Object data, int position) {
changeData();
}
});
}
private void changeData() {
DiffUtilCallback callback = new DiffUtilCallback();
callback.setOldList(mAdapter.getDataList());
List<ResourceBean> newList = new ArrayList<>();
for (int i = 'A'; i < 'D'; i++) {
for (int j = 0; j < 15; j++) {
ResourceBean resourceBean = new ResourceBean();
resourceBean.setSubject("學(xué)科" + (char) i);
resourceBean.setName("吃飯課" + j);
newList.add(resourceBean);
}
}
ResourceBean r = new ResourceBean();
r.setSubject("體育課");
r.setName("---->666666");
newList.add(4, r);
callback.setNewList(newList);
//這是主線程症昏。下面有案例放在了子線程中
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);//子線程計(jì)算差異
diffResult.dispatchUpdatesTo(mAdapter);
mAdapter.setData(newList);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != rv) rv.setAdapter(null);
}
}
而關(guān)聯(lián)操作關(guān)鍵的代碼也就2
行
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);
diffResult.dispatchUpdatesTo(adapter);//與Adapter進(jìn)行關(guān)聯(lián)
這時(shí)計(jì)算兩個(gè)List
的過程是放在UI主線程
。到了實(shí)際開發(fā)中父丰,數(shù)據(jù)量往往會(huì)比較大肝谭,計(jì)算差異化這一步,最好做些處理放在一個(gè)子線程中
在上一篇RecyclerView.Adapter學(xué)習(xí)的1.5小節(jié)一系列的notifyData方法
中蛾扇,移除或者增加同類型對(duì)象的item
時(shí)攘烛,說會(huì)感覺卡頓,使用DiffUtil
感覺好多了镀首,可能心理作用坟漱。。更哄。
如果只是想做個(gè)贊
芋齿,感覺沒必要使用DiffUtil
,RecycelrView.Adapter
提供的局部刷新感覺蠻好用的了成翩。有一個(gè)特別適合使用的場(chǎng)景便是下拉刷新
觅捆,不僅有動(dòng)畫,效率也有提高麻敌,尤其是下拉刷新
操作后栅炒,Adapter
內(nèi)集合數(shù)據(jù)并沒有發(fā)生改變,不需要進(jìn)行重新繪制RecyclerView
時(shí)
2. DiffUtil <p>
DiffUtil.DiffResult
和DiffUtil.Callback
是DiffUtil
的兩個(gè)內(nèi)部類术羔。DiffUtil
對(duì)外提供的public
方法只有2
個(gè)
方法1:
/**
* Calculates the list of update operations that can covert one list into the other one.
*
* @param cb The callback that acts as a gateway to the backing list data
*
* @return A DiffResult that contains the information about the edit sequence to convert the old list into the new list.
*/
public static DiffResult calculateDiff(Callback cb) {
return calculateDiff(cb, true);
}
這個(gè)方法用于計(jì)算newList
和oldList
的差異赢赊,在內(nèi)部計(jì)算出后的操作便是將兩個(gè)列表轉(zhuǎn)換成為另一個(gè)新的集合,但轉(zhuǎn)換過程并不用再操心的
在方法內(nèi)级历,調(diào)用了兩個(gè)參數(shù)的calculateDiff(cb, true)
释移,便是方法2
方法2:
/**
* Calculates the list of update operations that can covert one list into the other one.
* <p>
* If your old and new lists are sorted by the same constraint and items never move (swap positions), you can disable move detection which takes <code>O(N^2)</code> time where N is the number of added, moved, removed items.
*
* @param cb The callback that acts as a gateway to the backing list data
* @param detectMoves True if DiffUtil should try to detect moved items, false otherwise.
*
* @return A DiffResult that contains the information about the edit sequence to convert the old list into the new list.
*/
public static DiffResult calculateDiff(Callback cb, boolean detectMoves) {
...
//做過修改的Eugene W. Myers’s difference算法
final Snake snake = diffPartial(cb, range.oldListStart, range.oldListEnd, range.newListStart, range.newListEnd, forward, backward, max);
...
return new DiffResult(cb, snakes, forward, backward, detectMoves);
-
boolean detectMoves:是否檢測(cè)
item
是否移動(dòng),使用方法1
默認(rèn)為ture
鱼喉,這樣相對(duì)fasle
也會(huì)耗時(shí)一些
具體哪種場(chǎng)景下設(shè)置為false秀鞭,目前還不了解,有知道的同學(xué)請(qǐng)留言告訴一聲
在這個(gè)方法中扛禽,calculateDiff()
算是整個(gè)DiffUtil
的核心操作锋边,計(jì)算差異化操作,里面涉及到的算法以后再進(jìn)行學(xué)習(xí)
最后返回了一個(gè)DiffResult
對(duì)象编曼,這個(gè)對(duì)象內(nèi)部封裝著進(jìn)行了差異化比較操作后的轉(zhuǎn)換的數(shù)據(jù)集合豆巨。這個(gè)對(duì)象內(nèi)部涉及到的轉(zhuǎn)換操作,暫時(shí)也不打算進(jìn)行學(xué)習(xí)掐场,等對(duì)于DiffUtil
的使用相對(duì)熟練一些后往扔,再進(jìn)行學(xué)習(xí)
2.1 DiffUtil.Callback <p>
在這個(gè)抽象類中贩猎,一共有5個(gè)抽象方法:
方法 | 作用 |
---|---|
public abstract int getOldListSize() |
新集合的size |
public abstract int getNewListSize() |
舊集合的size |
public abstract boolean areItemsTheSame() |
判斷兩個(gè)集合中Object 是否相同 |
public abstract boolean areContentsTheSame() |
檢查兩個(gè)item 的對(duì)象內(nèi)容是否相同 |
public Object getChangePayload() |
@Nullable ,非必需重寫的方法萍膛,得到封裝新舊集合中兩個(gè)item 負(fù)載對(duì)象吭服,默認(rèn)返回null
|
前兩個(gè)方法很好理解,后面3個(gè)方法需要根據(jù)源碼中的注釋來學(xué)習(xí)
2.1.1 areItemsTheSame()判斷Item中Objecct是否相同 <p>
源碼:
/**
* Called by the DiffUtil to decide whether two object represent the same Item.
* 進(jìn)行比較新舊集合中在oldItemPosition與newItemPosition兩個(gè)對(duì)象是否相同
*
* For example, if your items have unique ids, this method should check their id equality.
*例如蝗罗,當(dāng)集合中的對(duì)象有唯一的標(biāo)記ids時(shí)艇棕,就比較兩個(gè)對(duì)象的ids
*
* @param oldItemPosition The position of the item in the old list
* 對(duì)象在舊的集合中的position
* @param newItemPosition The position of the item in the new list
* 對(duì)象在新的集合中的position
* @return True if the two items represent the same object or false if they are different.
* 返回比較結(jié)果
*/
public abstract boolean areItemsTheSame(int oldItemPosition, int newItemPosition);
這個(gè)方法的返回結(jié)果會(huì)對(duì)areContentsTheSame()
方法有影響
2.1.2 areContentsTheSame()判斷Objecct中的內(nèi)容是否相同<p>
源碼:
/**
* Called by the DiffUtil when it wants to check whether two items have the same data.
* 比較新舊集合對(duì)象中的內(nèi)容是否一樣
* DiffUtil uses this information to detect if the contents of an item has changed.
* DiffUtil利用這個(gè)方法的返回值來檢測(cè)一個(gè)對(duì)象是否發(fā)生變化
*
* DiffUtil uses this method to check equality instead of {@link Object#equals(Object)}
* DiffUtil使用這個(gè)方法代替equals()來檢測(cè)是否相等
* so that you can change its behavior depending on your UI.
* 可以根據(jù)UI需求來改變返回值
*
* For example, if you are using DiffUtil with a {@link android.support.v7.widget.RecyclerView.Adapter RecyclerView.Adapter}, you should return whether the items' visual representations are the same.
* 例如,在配合RecyclerView.Adapter使用時(shí)串塑,需要返回RecycelrView的item視覺效果是否一致
*這里視覺效果應(yīng)該指的就是動(dòng)畫吧
*
* This method is called only if {@link #areItemsTheSame(int, int)} returns{@code true} for these items.
*這個(gè)方法只有在areItemsTheSame()方法返回ture時(shí)才會(huì)被調(diào)用
* @param oldItemPosition The position of the item in the old list
* @param newItemPosition The position of the item in the new list which replaces the oldItem
* @return True if the contents of the items are the same or false if they are different.
*/
public abstract boolean areContentsTheSame(int oldItemPosition, int newItemPosition);
只有當(dāng)areContentsTheSame()
方法返回true
時(shí)沼琉,這個(gè)方法才會(huì)被掉y用。不難理解桩匪,只有聽一個(gè)類型的對(duì)象才可以比較的意義
2.1.3 getChangePayload()得到封裝差異化信息的對(duì)象 <p>
源碼:
/**
* When {@link #areItemsTheSame(int, int)} returns {@code true} for two items and {@link #areContentsTheSame(int, int)} returns false for them, DiffUtil calls this method to get a payload about the change.
* 當(dāng)areItemsTheSame()返回true并且areContentsTheSame返回false打瘪,DiffUtil便會(huì)調(diào)用這個(gè)方法將兩個(gè)item的差異封裝在一個(gè)負(fù)載對(duì)象中
*
* <p>
* For example, if you are using DiffUtil with {@link RecyclerView}, you can return the particular field that changed in the item and your{@link android.support.v7.widget.RecyclerView.ItemAnimator ItemAnimator} can use that information to run the correct animation.
* 例如,當(dāng)配合RecyclerView使用DiffUtil時(shí)傻昙,可以將新的item改變的特定屬性返回闺骚,還可以使用返回的差異屬性利用RecyclerView.ItemAnimator使用改變的動(dòng)畫
*
* <p>
* Default implementation returns {@code null}.
*默認(rèn)返回為null
* @param oldItemPosition The position of the item in the old list
* @param newItemPosition The position of the item in the new list
*
* @return A payload object that represents the change between the two items.
*/
@Nullable
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return null;
}
使用這個(gè)方法,有特定的條件:
areItemsTheSame()返回true屋匕,areContentsTheSame返回false
這個(gè)方法還要重寫RecyclerView.Adapter
的onBindViewHolder(RecyclerHolder holder, int position, List<Object> payloads)
DiffUtil
將返回的封裝差異化的對(duì)象存儲(chǔ)在一個(gè)List
集合中葛碧,集合payloads
對(duì)象不會(huì)為null
,但可能會(huì)為empty
过吻,也就是只有集合對(duì)象进泼,而集合中卻是空的。在onBindViewHolder()
需要加判斷payloads.isEmpty()
纤虽,若為empty
就調(diào)用兩個(gè)參數(shù)的onBindViewHolder()
簡(jiǎn)單使用:
在DiffUtilCallback
中對(duì)應(yīng):
/**
* 返回的特定的差異化結(jié)果
*/
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
ResourceBean oldBean = oldList.get(oldItemPosition);
ResourceBean newBean = newList.get(newItemPosition);
Bundle diffBundle = new Bundle();
if (!oldBean.getName().equals(newBean.getName())) {
diffBundle.putSerializable("newBean",newBean);
}
return diffBundle;
}```
**在Adapter中對(duì)應(yīng):**
```java
@Override
public void onBindViewHolder(RecyclerHolder holder, int position, List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
if (payloads.isEmpty()) {
Log.e("isEmpty", "---->" + payloads.isEmpty());
onBindViewHolder(holder, position);
}else {
Log.e("isEmpty", "---->no null");
Bundle bundle = (Bundle) payloads.get(0);
ResourceBean resourceBean = (ResourceBean) bundle.get("newBean");
if (null == resourceBean) return;
// Log.e("change", "---->" + change);
holder.textView.setText(resourceBean.getSubject() + "--->" + resourceBean.getName());
}
}
注意要先判斷payloads
中是否含有差異化數(shù)據(jù)
子線程模擬網(wǎng)絡(luò)請(qǐng)求乳绕,完整的Activity代碼:
public class DiffUtilActivity extends AppCompatActivity {
private RecyclerView rv;
private PayloadAdapter mAdapter;
private StaticHandler mHandler = null;
private static final int ADD_DATA = 2 << 5;
private static final int CHANGE_DATA = 2 << 6;
private List<ResourceBean> oldList;
private List<ResourceBean> newList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diff_util);
init();
}
private void init() {
mHandler = new StaticHandler(DiffUtilActivity.this);
rv = (RecyclerView) findViewById(R.id.rv_diff_util_activity);
//布局管理器
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
rv.setLayoutManager(manager);
//設(shè)置ItemDecoration
rv.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
//適配器
mAdapter = new PayloadAdapter(rv);
rv.setAdapter(mAdapter);
//設(shè)置點(diǎn)擊事件
mAdapter.setItemListener(new PayloadAdapter.onRecyclerItemClickerListener() {
@Override
public void onRecyclerItemClick(View view, Object data, int position) {
changeData();
}
});
//添加數(shù)據(jù)
addData();
}
public static class StaticHandler extends Handler {
private final WeakReference<DiffUtilActivity> mWeakReference;
private StaticHandler(DiffUtilActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
DiffUtilActivity activity = mWeakReference.get();
if (null != activity) {
PayloadAdapter adapter = activity.mAdapter;
if (msg.what == ADD_DATA) {
List<ResourceBean> list = activity.oldList;
DiffUtil.DiffResult diffResult = (DiffUtil.DiffResult) msg.obj;
diffResult.dispatchUpdatesTo(adapter);
adapter.setData(list);
// adapter.notifyDataSetChanged(); //由上面代替
} else if (msg.what == CHANGE_DATA) {
List<ResourceBean> newData = activity.newList;
DiffUtil.DiffResult diffResult = (DiffUtil.DiffResult) msg.obj;
diffResult.dispatchUpdatesTo(adapter);
adapter.setData(newData);
}
}
}
}
/**
* 點(diǎn)擊之后,更改數(shù)據(jù)
*/
private void changeData() {
new Thread(new Runnable() {
@Override
public void run() {
Message message = mHandler.obtainMessage();
DiffUtilCallback callback = new DiffUtilCallback();
callback.setOldList(mAdapter.getDataList());
newList = new ArrayList<>();
//模擬下拉刷新數(shù)據(jù)沒有變化
// for (int i = 'A'; i < 'D'; i++) {
// for (int j = 0; j < 15; j++) {
// ResourceBean resourceBean = new ResourceBean();
// resourceBean.setSubject("學(xué)科" + (char) i);
// resourceBean.setName("資料" + j);
// newList.add(resourceBean);
// }
// }
for (int i = 'A'; i < 'D'; i++) {
for (int j = 0; j < 15; j++) {
ResourceBean resourceBean = new ResourceBean();
resourceBean.setSubject("學(xué)科" + (char) i);
resourceBean.setName("吃飯課" + j);
newList.add(resourceBean);
}
}
ResourceBean r = new ResourceBean();
r.setSubject("體育課");
r.setName("---->666666");
newList.add(4, r);
callback.setNewList(newList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);//子線程計(jì)算差異
message.what = CHANGE_DATA;
message.obj = diffResult;
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendMessage(message);
}
}).start();
}
/**
* 第一次加入數(shù)據(jù)
*/
private void addData() {
new Thread(new Runnable() {
@Override
public void run() {
Message message = mHandler.obtainMessage();
DiffUtilCallback callback = new DiffUtilCallback();
callback.setOldList(mAdapter.getDataList());
oldList = new ArrayList<>();
for (int i = 'A'; i < 'D'; i++) {
for (int j = 0; j < 15; j++) {
ResourceBean resourceBean = new ResourceBean();
resourceBean.setSubject("學(xué)科" + (char) i);
resourceBean.setName("資料" + j);
oldList.add(resourceBean);
}
}
try {
TimeUnit.MILLISECONDS.sleep(500);//模擬網(wǎng)絡(luò)耗時(shí)
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.setNewList(oldList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);//子線程計(jì)算差異
message.what = ADD_DATA;
message.obj = diffResult;
mHandler.sendMessage(message);
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != rv) rv.setAdapter(null);
}
}
補(bǔ)充:
2016 12月8號(hào) 00:16 發(fā)現(xiàn)之前寫的有嚴(yán)重錯(cuò)誤逼纸,已經(jīng)修改洋措。改代碼一直到1:02,越看越感覺代碼爛杰刽,困了菠发,先睡覺,以后對(duì)DiffUtil
再熟悉一點(diǎn)再來修改
3.最后 <p>
這篇學(xué)習(xí)記錄得稀里糊涂的贺嫂,希望不會(huì)坑到看博客的同學(xué)
本人很菜滓鸠,有錯(cuò)誤請(qǐng)指出
共勉 :)