Android RecyclerView刪除多個選中的item 及 局部刷新

Android RecyclerView刪除多個選中的item 及 局部刷新

最近看了一個慕課網上的實戰課, Android通用框架設計與完整電商APP開發 ,這個課也是2/3年之前的視頻了,所以購物車功能的有些地方不太對了,我就優化了一下,主要是兩個方面:

  1. 刪除多個選中的item
  2. 局部刷新

關於所有item的選中狀態爲選中時,recyclerview外部的全選按鈕狀態的更新,加一個回調就可以實現,具體源碼可以去我的 碼雲 參考,主要是ShopCartAdapterShopCartDelegate 兩個類,都在com.wll.ec.fast.main.cart 包下。

這裏的使用了BaseRecyclerViewAdapterHelper,不太瞭解的同學可以先去github 上 瞭解一下。

刪除多個選中的item

首先是刪除多個選中的商品後數據顯示錯誤問題,而且總價是顯示所有未選中和選中商品的總價,刪除商品後總價並沒有改變,我對此處進行了優化,總價是隨着商品選中狀態的改變而改變的,且若刪除選中的商品總價也會改變,效果圖對比如下:
在這裏插入圖片描述
可以看到最後兩個怎麼點擊也刪除不了。而且,總價變化也不對。
來看一下改進之後的效果,如下:
在這裏插入圖片描述
在這裏插入圖片描述
刪除選中item的思路如下:首先要記錄是哪些位置的item被選中了,將選中的對應位置數據從adapter的數據中刪除,並調用

notifyItemRemoved(int position)
notifyItemRangeRemoved(int positionStart, int itemCount)

注意,如果不調用上面兩個方法,而是隻刪除數據並更新數據,最後再notifyItemRangeRemoved的話會導致數據錯亂,下面附效果圖:
在這裏插入圖片描述
最後我們要把數據中position位置後面的數據中記錄該條數據位置信息的數據更新。如果不這麼做的話,會導致後續刪除position 位置的數據時,刪除的是其他位置的數據,如下圖:
在這裏插入圖片描述
所以一定要記得更新數據。

相關代碼如下:

	@OnClick(R2.id.tv_top_shop_cart_remove_selected)
    void onClickRemoveSelectedItem() {
        double subPrice = 0;
        final List<MultipleItemEntity> data = mAdapter.getData();
        //要刪除的數據
        final List<MultipleItemEntity> deleteEntities = new ArrayList<>();
        for (MultipleItemEntity entity : data) {
            final boolean isSelected = entity.getField(ShopCartItemFields.IS_SELECTED);
            if (isSelected) {
                deleteEntities.add(entity);
                subPrice = subPrice + ((double) entity.getField(ShopCartItemFields.PRICE)) *
                        (int) entity.getField(ShopCartItemFields.COUNT);
            }
        }
        
        int size = deleteEntities.size();
        int entityPosition = 0;
        for (int i = size - 1; i >= 0; i--) {
            entityPosition = deleteEntities.get(i).getField(ShopCartItemFields.POSITION);
            if (entityPosition < mAdapter.getItemCount()) {
                // mAdapter.getData().remove(entityPosition);
                mAdapter.remove(entityPosition);
            }
        }
        mAdapter.updateItemRangeFieldPosition(entityPosition);
//        mAdapter.notifyItemRangeRemoved(entityPosition, mAdapter.getItemCount() - entityPosition);
        updateTotalPrice(subPrice);
        checkItemCount();
    }

注意,此處remove的時候是for循環是從後面size-1先開始的,如果從前面開始,仔細想一下,刪除第一個,要notifyItemRangeRemoved 第一個後面所有的,然後下面還要繼續循環,如果我們從後面開始,那麼隨着item數量的減少,需要notifyItemRangeRemoved數量就減少。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

局部刷新

下面附三種方法對比圖:
notifyDataSetChanged():
在這裏插入圖片描述
notifyItemRangeChanged(int positionStart, int itemCount):
在這裏插入圖片描述
notifyItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload):
在這裏插入圖片描述

相關代碼如下:

    @OnClick(R2.id.icon_shop_cart_select_all)
    void onClickSelectAll() {
        boolean isSelectedAll = mAdapter.getIsSelectedAll();
        if (isSelectedAll){
            mIconSelectAll.setTextColor(Color.GRAY);
        } else {
            mIconSelectAll.setTextColor(ContextCompat.getColor(getContext(), R.color.app_main));
        }
        mAdapter.setIsSelectedAll(!isSelectedAll);
//        mAdapter.notifyDataSetChanged();
//        mAdapter.notifyItemRangeChanged(0, mAdapter.getItemCount());
        mAdapter.notifyItemRangeChanged(0, mAdapter.getItemCount(), "checkBtn");
        mAdapter.updateAllSelected(!isSelectedAll);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章