局部更新方法
1.使用Diffutil進行數(shù)據(jù)的比較
【Android】詳解7.0帶來的新工具類:DiffUtil
1.1一個相對完整的例子
Android高性能列表:RecyclerView + DiffUtil
分析:
操作過程主要是分為兩部,一步檢出有變化的數(shù)據(jù),一步定點刷新。下面貼出的代碼是完成檢索后,刷新數(shù)據(jù)的過程。方法很簡單就不一一解釋了,但是由此得出一個啟發(fā),假如我自己知道具體哪個數(shù)據(jù)有變化,是不是就直接省去了第一步繁瑣的檢索過程,直接定點刷新,是的,具體看方法二。
public void dispatchUpdatesTo(final RecyclerView.Adapter adapter) {
dispatchUpdatesTo(new ListUpdateCallback() {
@Override
public void onInserted(int position, int count) {
adapter.notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
adapter.notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
adapter.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count, Object payload) {
adapter.notifyItemRangeChanged(position, count, payload);
}
});
}
2.使用定點更新的方法:
當我知道具體哪些數(shù)據(jù)需要刷新的時候,存入bunder利用notifyItemChanged(int position, Object payload)實現(xiàn)更新。
Android RecyclerView 真正的布局刷新的正確方式
方法使用
項目中,在開發(fā)相冊模塊過程中,大哥提了兩個需求:一個是在已選相冊的右上角顯示“是第幾張被選擇的”,而且要局部刷新。第二個則是更換相冊時實現(xiàn)局部刷新。
第一個的實現(xiàn)采用的是方法二,因為我知道具體是第幾張需要被刷新,然后將需要刷新的數(shù)據(jù)打包發(fā)給adapter直接顯示刷新就好了。
實現(xiàn)具體代碼
1.圖片存儲bean類
因為項目中還有其他的邏輯,所以寫了一個bean類,但是如果你的邏輯沒有很多,完全可以不用,但是你必須要記錄圖片的位置,方法自選哈。
public class TemBean {
private String mPath;//圖片路徑
private int mPotion;//圖片的位置
public TemBean(String mPath, int mPotion) {
this.mPath = mPath;
this.mPotion = mPotion;
}
public String getmPath() {
return mPath;
}
public void setmPath(String mPath) {
this.mPath = mPath;
}
public int getmPotion() {
return mPotion;
}
public void setmPotion(int mPotion) {
this.mPotion = mPotion;
}
@Override
public String toString() {
return "TemBean{" +
"mPath='" + mPath + '\'' +
", mPotion='" + mPotion + '\'' +
'}';
}
}
2.刷新操作
//selectPics1 已經(jīng)選擇的圖片的集合
//list 數(shù)據(jù)源:
for (int i = start; i < selectPics1.size(); i++) {
for (int j = 1; j < list.size(); j++) {
if (list.get(j).getPath().equals(selectPics1.get(i).getmPath())) {
Bundle bundle = new Bundle();
bundle.putString("number", (selectPics.indexOf(selectPics1.get(i).getmPath()) + 1) + "");
notifyItemChanged(j, bundle);
continue;
}
}
}
3.onBindViewHolder的操作
@Override
public void onBindViewHolder(MyHolderView holder, int position, List<Object> payloads) {
if (payloads.isEmpty())
onBindViewHolder(holder, position);
else {
Bundle bundle = (Bundle) payloads.get(0);
for (String key : bundle.keySet()) {
switch (key) {
case "number":
holder.button.setImageResource(R.drawable.select_shape);
holder.pic.setColorFilter(0x80000000);
//更改圖片右上角的數(shù)字
holder.pager.setText((CharSequence) bundle.get(key));
break;
}
}
}
}
第二個需求,因為涉及到的數(shù)據(jù)有點多,所以不適合方法一的使用,所以調(diào)用diffutil,讓其幫助我們?nèi)ニ阉鞒鏊杏凶兓臄?shù)據(jù),然后定點刷新,需要注意的是刷選的條件要寫全。
開始,我只是利用僅含圖片路徑的方式去檢索,以為僅僅路徑就可以了,因為也沒有其他內(nèi)容,所以就沒有寫areContentsTheSame方法中的邏輯,但是出現(xiàn)的問題是數(shù)據(jù)的已經(jīng)更改的部分不刷新的問題,所以沒辦法,才添加了opsition變量的對照。
public class DiffCallBack extends DiffUtil.Callback {
private List<PicVideoBean> mOldDatas, mNewDatas;//看名字
public DiffCallBack(List<PicVideoBean> mOldDatas, List<PicVideoBean> mNewDatas) {
this.mOldDatas = mOldDatas;
this.mNewDatas = mNewDatas;
}
@Override
public int getOldListSize() {
return mOldDatas != null ? mOldDatas.size() : 0;
}
@Override
public int getNewListSize() {
return mNewDatas != null ? mNewDatas.size() : 0;
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
if (mOldDatas.get(oldItemPosition) == null && mNewDatas.get(newItemPosition) != null) {
return false;
}
if (mOldDatas.get(oldItemPosition) != null && mNewDatas.get(newItemPosition) == null) {
return false;
}
if (mOldDatas.get(oldItemPosition) == null && mNewDatas.get(newItemPosition) == null) {
return true;
}
return mOldDatas.get(oldItemPosition).getPath().equals(mNewDatas.get(newItemPosition).getPath());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
PicVideoBean beanOld = mOldDatas.get(oldItemPosition);
PicVideoBean beanNew = mNewDatas.get(newItemPosition);
return beanOld.getmPosition().equals(beanNew.getmPosition()); //默認兩個data內(nèi)容是相同的
}
好了到這里,有不對的地方歡迎留言
喵印~~