最近看了一个慕课网上的实战课, Android通用框架设计与完整电商APP开发
,这个课也是2/3年之前的视频了,所以购物车功能的有些地方不太对了,我就优化了一下,主要是两个方面:
关于所有item的选中状态为选中时,recyclerview外部的全选按钮状态的更新,加一个回调就可以实现,具体源码可以去我的 码云 参考,主要是ShopCartAdapter
和 ShopCartDelegate
两个类,都在com.wll.ec.fast.main.cart
包下。
这里的使用了BaseRecyclerViewAdapterHelper,不太了解的同学可以先去github 上 了解一下。
首先是删除多个选中的商品后数据显示错误问题,而且总价是显示所有未选中和选中商品的总价,删除商品后总价并没有改变,我对此处进行了优化,总价是随着商品选中状态的改变而改变的,且若删除选中的商品总价也会改变,效果图对比如下:
可以看到最后两个怎么点击也删除不了。而且,总价变化也不对。
来看一下改进之后的效果,如下:
删除选中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);
}