Android之RecyclerView的局部刷新

局部更新方法

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)容是相同的
    }

好了到這里,有不對的地方歡迎留言
喵印~~

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容