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

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

20161209152143632.gif

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

下面开始来看代码

Activity界面是这样的

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的布局

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上上传项目,还不是很熟悉项目展示有点问题,不过不影响下载,我之后再改改)

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

  1. android登录操作代码,Android Studio实现第三方QQ登录操作代码

    来看看效果图吧 实现QQ登录了, 新建一个项目工程 ,然后把我们刚才下载的SDK解压将jar文件夹中的jar包拷贝到我们的项目libs中 导入一个下面架包就可以 项目结构如下 打开我们的清单文件And ...

  2. android studio操作手机相机,Android Studio 调用Camera实现拍照功能

    首先创建一个SurfaceHolder实现对SurfaceView的回调,然后重写SurfaceCreate函数,实现对Camera的初始化等一系列工作:代码如下: @Override public ...

  3. Android自定义操作栏示例教程

    In this tutorial we will create an app that consists of Android Custom Action Bar with a custom layo ...

  4. Android 中编写一个简易购物车,商品包括商品名称,单价,数量,可以对商品进行增删改查功能。(ArrayList,SQLite)

    Android 中编写一个简易购物车,商品包括商品名称,单价,数量,可以对商品进行增删改查功能.(ArrayList,SQLite) 布局(activity_main.xml): <?xml v ...

  5. Android一点 仿淘宝购物车动画

    首先看看ios上的淘宝购物车的动画效果ios淘宝购物车动画 我们实现的效果 看特效是分为两个界面,一个是主view,一个是弹出层.弹出层是用dialog实现的,只是加入了弹出的动画,这里就不分析了,我 ...

  6. android购物车代码简述,Android实现简单购物车功能

    本文实例为大家分享了Android实现购物车功能的具体代码,供大家参考,具体内容如下 MainActivity布局: android:layout_width="match_parent&q ...

  7. android 购物车 简书,Android仿饿了么购物车效果

    先看下效果图: ezgif-1-8f133ca916.gif 1.首先列表布局采用Recycleview android:id="@+id/container" android:l ...

  8. Android把商品添加到购物车的动画效果(贝塞尔曲线)

    当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,具体代码如下: 实现效果如图: 思路: 确定动画的起终点 在起终点之间使用二次贝塞尔曲线填充起终点之间的点的 ...

  9. android购物车栏,Android怎么实现二级列表购物车功能

    Android怎么实现二级列表购物车功能 发布时间:2021-04-16 12:45:40 来源:亿速云 阅读:61 作者:小新 小编给大家分享一下Android怎么实现二级列表购物车功能,希望大家阅 ...

最新文章

  1. 「Python」一文读懂装饰器
  2. Scott Mitchell的ASP.NET2.0数据指南中文版索引
  3. J2EE (六) 详解 java 中文乱码
  4. 【Paper】2003_Consensus Problems in Networks of Agents with Switching Topology and Time-Delays
  5. 037——VUE中表单控件处理之表单修饰符:lazy/number/trim
  6. sudo修改文件夹名字_修改mac os帐户的短名称和个人文件夹
  7. Python3的bytes/str之别
  8. 采样定理实验报告matlab,matlab验证时域采样定理试验报告
  9. SpringBoot : Consider defining a bean of type xxx in your configuration.
  10. python中双向索引_对索引Include子句的深入分析
  11. Linux系统安全加固策略(二)
  12. Liunx 项目部署及域名访问
  13. docker nginx 反向代理
  14. Json笔记-高德地铁数据分析
  15. 动态网页抓取数据软件
  16. css各种字体英文名称
  17. 微波雷达感应模块,人体存在感应雷达技术,广告屏智能感应显示
  18. java向指定用户极光推送_【极光推送】给指定用户发送消息
  19. 怎么修改html的空格大小,css设置空格宽度间距样式
  20. java外文资料_java外文文献(毕业设计).doc

热门文章

  1. 李嘉诚在香港做支付,为何要牵手马云?
  2. 学习51单片机串口工作方式及应用
  3. kafka的Rebalance问题分析(续)
  4. Linux——vim/vi文本编辑器
  5. nginx正向代理配置
  6. 怎么吃才能促进孩子长个子?
  7. xcode8 cocoapods 执行 pod spec lint 报错
  8. Atitit 最近资料文章列表r9 r8 月份 attilax总结
  9. sql中的日期比较(年,月,日)
  10. Linux 文件和目录管理