android 购物车操作并发,Android 购物车页面和逻辑实现

之前在CSDN上写了几篇..现在想在简书上也写写,所以就过来试试....嘻嘻嘻~~~好,,进入正题....

这是之前在做的项目中的一个功能 购物车! 我这个购物车业务逻辑还算可以吧,不算太难,但由于我是第一次做,所以也碰到了很多细节上的问题...所以我想总结下来,方便以后学习和使用..好了先看看效果吧!

1dc783effa05

20161209152143632.gif

目前我做的功能除了结算就这些了...

下面开始来看代码

Activity界面是这样的

1dc783effa05

image.png

首先是Activity 布局xml

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:id="@+id/shopping_title"

layout="@layout/layout_title" />

android:id="@+id/tv_edit"

android:layout_width="wrap_content"

android:layout_height="25dp"

android:layout_gravity="right"

android:layout_margin="10dp"

android:text="编辑"

android:textSize="18dp" />

android:layout_width="match_parent"

android:layout_height="1dp"

android:layout_below="@id/tv_edit"

android:background="@color/gray3" />

android:id="@+id/list_shopping_cart"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_below="@id/tv_edit"

android:layout_weight="1"

android:scrollbars="none" />

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="@color/gray3" />

android:id="@+id/rl_bottom"

android:layout_width="match_parent"

android:layout_height="50dp"

android:layout_alignParentBottom="true"

android:background="@color/white">

android:id="@+id/ck_all"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_centerVertical="true"

android:button="@drawable/check_box_style"

android:checkMark="?android:attr/listChoiceIndicatorMultiple"

android:gravity="center"

android:paddingLeft="10dp"

android:scaleX="0.6"

android:scaleY="0.6"

android:text="全选"

android:textAppearance="?android:attr/textAppearanceLarge"

android:textColor="@color/desccolor" />

android:id="@+id/tv_settlement"

android:layout_width="80dp"

android:layout_height="match_parent"

android:layout_alignParentRight="true"

android:background="@color/desccolor"

android:gravity="center"

android:text="结算(0)"

android:textColor="@color/white" />

android:id="@+id/tv_show_price"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_toLeftOf="@id/tv_settlement"

android:gravity="center"

android:padding="5dp"

android:text="合计:0.00"

android:textColor="@color/desccolor" />

再来看 ListView item的布局

1dc783effa05

image.png

item 布局xml

android:layout_width="match_parent"

android:layout_height="190dp"

android:orientation="vertical">

android:id="@+id/ck_chose"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="8dp"

android:button="@drawable/check_box_style"

android:scaleX="0.6"

android:scaleY="0.6" />

android:id="@+id/iv_show_pic"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="10dp"

android:layout_toRightOf="@id/ck_chose"

android:background="@mipmap/demo" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="15dp"

android:layout_marginTop="30dp"

android:layout_toRightOf="@id/iv_show_pic"

android:orientation="vertical">

android:id="@+id/tv_commodity_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="酒红色纯红色纯羊毛西服套装"

android:textColor="@color/black"

android:textStyle="bold" />

android:id="@+id/rl_edit"

android:layout_width="110dp"

android:layout_height="30dp"

android:orientation="horizontal"

android:visibility="gone">

android:id="@+id/iv_sub"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@mipmap/iv_sub" />

android:id="@+id/tv_show_num"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"

android:text="1"

android:textColor="@color/desccolor" />

android:id="@+id/iv_add"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentRight="true"

android:background="@mipmap/iv_add" />

android:layout_width="match_parent"

android:layout_height="0.7dp"

android:layout_alignParentBottom="true"

android:background="@color/black" />

android:id="@+id/tv_fabric"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="面料:"

android:textColor="@color/gray5" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/tv_dress"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="西服尺寸: 48"

android:textColor="@color/gray5" />

android:id="@+id/tv_pants"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="西裤尺寸: 68"

android:textColor="@color/gray5" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:orientation="horizontal">

android:id="@+id/tv_price"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="¥390"

android:textColor="@color/black"

android:textStyle="bold" />

android:id="@+id/tv_num"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="40dp"

android:text="x1"

android:textColor="@color/gray5" />

android:id="@+id/tv_delete"

android:layout_width="60dp"

android:layout_height="match_parent"

android:layout_alignParentRight="true"

android:background="@color/address_press"

android:gravity="center"

android:text="删除"

android:visibility="gone" />

好了 ,,布局就说完了 现在我们来看看逻辑部分

由于很多操作是在Activity中操作 ListView的item ,所以我这里选择的是接口回调,我感觉方便些..也许你会有更好的方法.

首先我们在 Adapter中定义了几个

/**

* 复选框接口

*/

public interface CheckInterface {

/**

* 组选框状态改变触发的事件

*

* @param position 元素位置

* @param isChecked 元素选中与否

*/

void checkGroup(int position, boolean isChecked);

}

/**

* 改变数量的接口

*/

public interface ModifyCountInterface {

/**

* 增加操作

*

* @param position 组元素位置

* @param showCountView 用于展示变化后数量的View

* @param isChecked 子元素选中与否

*/

void doIncrease(int position, View showCountView, boolean isChecked);

/**

* 删减操作

*

* @param position 组元素位置

* @param showCountView 用于展示变化后数量的View

* @param isChecked 子元素选中与否

*/

void doDecrease(int position, View showCountView, boolean isChecked);

/**

* 删除子item

*

* @param position

*/

void childDelete(int position);

}

再来看看Adapter 没啥可说的.. 注释我在代码写的还算详细 ,相信能看懂

public class ShoppingCartAdapter extends BaseAdapter {

private boolean isShow = true;//是否显示编辑/完成

private List shoppingCartBeanList;

private CheckInterface checkInterface;

private ModifyCountInterface modifyCountInterface;

private Context context;

public ShoppingCartAdapter(Context context) {

this.context = context;

}

public void setShoppingCartBeanList(List shoppingCartBeanList) {

this.shoppingCartBeanList = shoppingCartBeanList;

notifyDataSetChanged();

}

/**

* 单选接口

*

* @param checkInterface

*/

public void setCheckInterface(CheckInterface checkInterface) {

this.checkInterface = checkInterface;

}

/**

* 改变商品数量接口

*

* @param modifyCountInterface

*/

public void setModifyCountInterface(ModifyCountInterface modifyCountInterface) {

this.modifyCountInterface = modifyCountInterface;

}

@Override

public int getCount() {

return shoppingCartBeanList == null ? 0 : shoppingCartBeanList.size();

}

@Override

public Object getItem(int position) {

return shoppingCartBeanList.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

/**

* 是否显示可编辑

*

* @param flag

*/

public void isShow(boolean flag) {

isShow = flag;

notifyDataSetChanged();

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

final ViewHolder holder;

if (convertView == null) {

convertView = LayoutInflater.from(context).inflate(R.layout.item_shopping_cart_layout, parent, false);

holder = new ViewHolder(convertView);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

final ShoppingCartBean shoppingCartBean = shoppingCartBeanList.get(position);

holder.tv_commodity_name.setText(shoppingCartBean.getShoppingName());

holder.tv_fabric.setText("面料:" + shoppingCartBean.getFabric());

holder.tv_dress.setText("西服尺寸:" + shoppingCartBean.getDressSize());

holder.tv_pants.setText("西裤尺寸:" + shoppingCartBean.getPantsSize());

holder.tv_price.setText("¥:" + shoppingCartBean.getPrice());

holder.ck_chose.setChecked(shoppingCartBean.isChoosed());

holder.tv_show_num.setText(shoppingCartBean.getCount() + "");

holder.tv_num.setText("X" + shoppingCartBean.getCount());

//单选框按钮

holder.ck_chose.setOnClickListener(

new View.OnClickListener() {

@Override

public void onClick(View v) {

shoppingCartBean.setChoosed(((CheckBox) v).isChecked());

checkInterface.checkGroup(position, ((CheckBox) v).isChecked());//向外暴露接口

}

}

);

//增加按钮

holder.iv_add.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

modifyCountInterface.doIncrease(position, holder.tv_show_num, holder.ck_chose.isChecked());//暴露增加接口

}

});

//删减按钮

holder.iv_sub.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

modifyCountInterface.doDecrease(position, holder.tv_show_num, holder.ck_chose.isChecked());//暴露删减接口

}

});

//删除弹窗

holder.tv_delete.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

AlertDialog alert = new AlertDialog.Builder(context).create();

alert.setTitle("操作提示");

alert.setMessage("您确定要将这些商品从购物车中移除吗?");

alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

return;

}

});

alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

modifyCountInterface.childDelete(position);//删除 目前只是从item中移除

}

});

alert.show();

}

});

//判断是否在编辑状态下

if (isShow) {

holder.tv_commodity_name.setVisibility(View.VISIBLE);

holder.tv_fabric.setVisibility(View.VISIBLE);

holder.rl_edit.setVisibility(View.GONE);

holder.tv_delete.setVisibility(View.GONE);

} else {

holder.tv_commodity_name.setVisibility(View.GONE);

holder.tv_fabric.setVisibility(View.GONE);

holder.rl_edit.setVisibility(View.VISIBLE);

holder.tv_delete.setVisibility(View.VISIBLE);

}

return convertView;

}

//初始化控件

class ViewHolder {

ImageView iv_chose;

ImageView iv_show_pic, iv_sub, iv_add;

TextView tv_commodity_name, tv_fabric, tv_dress, tv_pants, tv_price, tv_num, tv_delete, tv_show_num;

CheckBox ck_chose;

RelativeLayout rl_edit;

public ViewHolder(View itemView) {

ck_chose = (CheckBox) itemView.findViewById(R.id.ck_chose);

iv_show_pic = (ImageView) itemView.findViewById(R.id.iv_show_pic);

iv_sub = (ImageView) itemView.findViewById(R.id.iv_sub);

iv_add = (ImageView) itemView.findViewById(R.id.iv_add);

tv_commodity_name = (TextView) itemView.findViewById(R.id.tv_commodity_name);

tv_fabric = (TextView) itemView.findViewById(R.id.tv_fabric);

tv_dress = (TextView) itemView.findViewById(R.id.tv_dress);

tv_pants = (TextView) itemView.findViewById(R.id.tv_pants);

tv_price = (TextView) itemView.findViewById(R.id.tv_price);

tv_num = (TextView) itemView.findViewById(R.id.tv_num);

tv_delete = (TextView) itemView.findViewById(R.id.tv_delete);

tv_show_num = (TextView) itemView.findViewById(R.id.tv_show_num);

rl_edit = (RelativeLayout) itemView.findViewById(R.id.rl_edit);

}

}

现在我们在来看看Activity 代码, 同样注释写的很详细

public class ShoppingCartActivity extends BaseActivity implements View.OnClickListener

, ShoppingCartAdapter.CheckInterface, ShoppingCartAdapter.ModifyCountInterface {

public TextView tv_title, tv_settlement, tv_show_price;

private TextView tv_all_check;

private CheckBox ck_all;

private ListView list_shopping_cart;

private ShoppingCartAdapter shoppingCartAdapter;

private TextView tv_edit;

private boolean flag = false;

private List shoppingCartBeanList = new ArrayList<>();

private boolean mSelect;

private double totalPrice = 0.00;// 购买的商品总价

private int totalCount = 0;// 购买的商品总数量

/**

* 批量模式下,用来记录当前选中状态

*/

private SparseArray mSelectState = new SparseArray();

@Override

protected int getLayout() {

return R.layout.layout_shopping_cart_activity;

}

@Override

protected void initView() {

tv_title = bindView(R.id.tv_title);

tv_title.setText("购物车");

list_shopping_cart = bindView(R.id.list_shopping_cart);

// list_shopping_cart.setOnItemClickListener(this);

ck_all = bindView(R.id.ck_all);

ck_all.setOnClickListener(this);

// ck_all.setOnCheckedChangeListener(this);

tv_show_price = bindView(R.id.tv_show_price);

tv_settlement = bindView(R.id.tv_settlement);

tv_settlement.setOnClickListener(this);

tv_edit = bindView(R.id.tv_edit);

tv_edit.setOnClickListener(this);

shoppingCartAdapter = new ShoppingCartAdapter(this);

shoppingCartAdapter.setCheckInterface(this);

shoppingCartAdapter.setModifyCountInterface(this);

list_shopping_cart.setAdapter(shoppingCartAdapter);

shoppingCartAdapter.setShoppingCartBeanList(shoppingCartBeanList);

}

@Override

protected void initData() {

for (int i = 0; i < 6; i++) {

ShoppingCartBean shoppingCartBean = new ShoppingCartBean();

shoppingCartBean.setShoppingName("高端大气上档次的T桖");

shoppingCartBean.setFabric("纯棉");

shoppingCartBean.setDressSize(48);

shoppingCartBean.setPantsSize(65);

shoppingCartBean.setPrice(60);

shoppingCartBean.setCount(2);

shoppingCartBeanList.add(shoppingCartBean);

}

}

@Override

public void onClick(View v) {

switch (v.getId()) {

//全选按钮

case R.id.ck_all:

if (shoppingCartBeanList.size() != 0) {

if (ck_all.isChecked()) {

for (int i = 0; i < shoppingCartBeanList.size(); i++) {

shoppingCartBeanList.get(i).setChoosed(true);

}

shoppingCartAdapter.notifyDataSetChanged();

} else {

for (int i = 0; i < shoppingCartBeanList.size(); i++) {

shoppingCartBeanList.get(i).setChoosed(false);

}

shoppingCartAdapter.notifyDataSetChanged();

}

}

statistics();

break;

case R.id.tv_edit:

flag = !flag;

if (flag) {

tv_edit.setText("完成");

shoppingCartAdapter.isShow(false);

} else {

tv_edit.setText("编辑");

shoppingCartAdapter.isShow(true);

}

break;

}

}

/**

* 单选

*

* @param position 组元素位置

* @param isChecked 组元素选中与否

*/

@Override

public void checkGroup(int position, boolean isChecked) {

shoppingCartBeanList.get(position).setChoosed(isChecked);

if (isAllCheck())

ck_all.setChecked(true);

else

ck_all.setChecked(false);

shoppingCartAdapter.notifyDataSetChanged();

statistics();

}

/**

* 遍历list集合

*

* @return

*/

private boolean isAllCheck() {

for (ShoppingCartBean group : shoppingCartBeanList) {

if (!group.isChoosed())

return false;

}

return true;

}

/**

* 统计操作

* 1.先清空全局计数器

* 2.遍历所有子元素,只要是被选中状态的,就进行相关的计算操作

* 3.给底部的textView进行数据填充

*/

public void statistics() {

totalCount = 0;

totalPrice = 0.00;

for (int i = 0; i < shoppingCartBeanList.size(); i++) {

ShoppingCartBean shoppingCartBean = shoppingCartBeanList.get(i);

if (shoppingCartBean.isChoosed()) {

totalCount++;

totalPrice += shoppingCartBean.getPrice() * shoppingCartBean.getCount();

}

}

tv_show_price.setText("合计:" + totalPrice);

tv_settlement.setText("结算(" + totalCount + ")");

}

/**

* 增加

*

* @param position 组元素位置

* @param showCountView 用于展示变化后数量的View

* @param isChecked 子元素选中与否

*/

@Override

public void doIncrease(int position, View showCountView, boolean isChecked) {

ShoppingCartBean shoppingCartBean = shoppingCartBeanList.get(position);

int currentCount = shoppingCartBean.getCount();

currentCount++;

shoppingCartBean.setCount(currentCount);

((TextView) showCountView).setText(currentCount + "");

shoppingCartAdapter.notifyDataSetChanged();

statistics();

}

/**

* 删减

*

* @param position 组元素位置

* @param showCountView 用于展示变化后数量的View

* @param isChecked 子元素选中与否

*/

@Override

public void doDecrease(int position, View showCountView, boolean isChecked) {

ShoppingCartBean shoppingCartBean = shoppingCartBeanList.get(position);

int currentCount = shoppingCartBean.getCount();

if (currentCount == 1) {

return;

}

currentCount--;

shoppingCartBean.setCount(currentCount);

((TextView) showCountView).setText(currentCount + "");

shoppingCartAdapter.notifyDataSetChanged();

statistics();

}

/**

* 删除

*

* @param position

*/

@Override

public void childDelete(int position) {

shoppingCartBeanList.remove(position);

shoppingCartAdapter.notifyDataSetChanged();

statistics();

}

}

整体的就是这样,,我说一下 我做的时候遇到的问题和解决办法

问题:当我单选一个一个选中后,全选按钮也会自动选中 ,但是当我取消一个item后 全选按钮没有自动取消 (正常是只有有一个item没有选中 全选按钮是不会选中的)

解决:首先解决问题要找到原因所在 ,造成这个Bug的原因是我CheckBox的点击事件用的是setOnCheckedChangeListener 后来换成了setOnClickListener 就好了 .

两者都能实现对CheckBox的状态改变的监听,但一般情况下,用的更多的是setOnCheckedChangeListener。因为,当CheckBox的状态不是通过点击事件改变,而是通过其他的方式改变时,比如setCheck(),setOnClickListener无法完成此种情况下的监听。OnCheckChangedListener监听CheckBox的状态,无论来自你的onClick事件还是其他。

问题: 就是在改变物品个数的是时候会出现复用!

解决: 原因就是我没有保存当前 改变后是值, 保存一下就OK了..

总体上就是这些了.......感兴趣的同学可以下载demo看看

Demo在这里----->https://github.com/HelloSinger/ShoppingCat

(第一次在github上上传项目,还不是很熟悉项目展示有点问题,不过不影响下载,我之后再改改)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值