Android RecyclerView删除多个选中的item 及 局部刷新

Android RecyclerView删除多个选中的item 及 局部刷新

    • 删除多个选中的item
    • 局部刷新

最近看了一个慕课网上的实战课, Android通用框架设计与完整电商APP开发 ,这个课也是2/3年之前的视频了,所以购物车功能的有些地方不太对了,我就优化了一下,主要是两个方面:

  1. 删除多个选中的item
  2. 局部刷新

关于所有item的选中状态为选中时,recyclerview外部的全选按钮状态的更新,加一个回调就可以实现,具体源码可以去我的 码云 参考,主要是ShopCartAdapterShopCartDelegate 两个类,都在com.wll.ec.fast.main.cart 包下。

这里的使用了BaseRecyclerViewAdapterHelper,不太了解的同学可以先去github 上 了解一下。

删除多个选中的item

首先是删除多个选中的商品后数据显示错误问题,而且总价是显示所有未选中和选中商品的总价,删除商品后总价并没有改变,我对此处进行了优化,总价是随着商品选中状态的改变而改变的,且若删除选中的商品总价也会改变,效果图对比如下:
Android RecyclerView删除多个选中的item 及 局部刷新_第1张图片
可以看到最后两个怎么点击也删除不了。而且,总价变化也不对。
来看一下改进之后的效果,如下:
Android RecyclerView删除多个选中的item 及 局部刷新_第2张图片
Android RecyclerView删除多个选中的item 及 局部刷新_第3张图片
删除选中item的思路如下:首先要记录是哪些位置的item被选中了,将选中的对应位置数据从adapter的数据中删除,并调用

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

注意,如果不调用上面两个方法,而是只删除数据并更新数据,最后再notifyItemRangeRemoved的话会导致数据错乱,下面附效果图:
Android RecyclerView删除多个选中的item 及 局部刷新_第4张图片
最后我们要把数据中position位置后面的数据中记录该条数据位置信息的数据更新。如果不这么做的话,会导致后续删除position 位置的数据时,删除的是其他位置的数据,如下图:
Android RecyclerView删除多个选中的item 及 局部刷新_第5张图片
所以一定要记得更新数据。

相关代码如下:

	@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数量就减少。
Android RecyclerView删除多个选中的item 及 局部刷新_第6张图片
Android RecyclerView删除多个选中的item 及 局部刷新_第7张图片
Android RecyclerView删除多个选中的item 及 局部刷新_第8张图片

局部刷新

下面附三种方法对比图:
notifyDataSetChanged():
Android RecyclerView删除多个选中的item 及 局部刷新_第9张图片
notifyItemRangeChanged(int positionStart, int itemCount):
Android RecyclerView删除多个选中的item 及 局部刷新_第10张图片
notifyItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload):
Android RecyclerView删除多个选中的item 及 局部刷新_第11张图片

相关代码如下:

    @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);
    }

你可能感兴趣的:(Android)