先上效果:

购物车实现使用的ExpandableListView,关于它的使用的就不在多说,网上的资料都非常多。
xml里面布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.xp.shoppingcart.MainActivity"><include layout="@layout/include_toolbar" /><ExpandableListView
        android:id="@+id/expandableListView"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:scrollbars="none"android:divider="@null"/><View
        android:layout_width="match_parent"android:layout_height="1dp"android:background="@color/divide_line"/><LinearLayout
        android:layout_width="match_parent"android:layout_height="49dp"android:background="@android:color/white"android:gravity="center_vertical"android:orientation="horizontal"><com.xp.shoppingcart.SmoothCheckBox
            android:id="@+id/cb_select_all"android:layout_width="24dp"android:layout_height="24dp"android:layout_marginLeft="15dp" /><TextView
            android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:layout_weight="0.69"android:text="全选"android:textColor="#333333"android:textSize="15sp" /><LinearLayout
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="end"android:orientation="vertical"><LinearLayout
                android:layout_width="wrap_content"android:layout_height="wrap_content"><TextView
                    android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="合计"android:textColor="#333333"android:textSize="15sp" /><TextView
                    android:id="@+id/tv_all_money"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="¥0"android:textColor="#FE3824"android:textSize="15sp" /></LinearLayout><TextView
                android:id="@+id/tv_transport"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="运费:¥0"android:textColor="#999999"android:textSize="11sp" /></LinearLayout><Button
            android:id="@+id/btn_settlement"android:layout_width="95dp"android:layout_height="match_parent"android:layout_marginLeft="15dp"android:background="#FE3824"android:text="结算(0)"android:textColor="@android:color/white"android:textSize="16sp" /></LinearLayout></LinearLayout>

初始化控件:

private void initView() {mExpandableListView = (ExpandableListView) findViewById(R.id.expandableListView);mCbSelectAll = (SmoothCheckBox) findViewById(R.id.cb_select_all);mTvAllMoney = (TextView) findViewById(R.id.tv_all_money);mBtnBuy = (Button) findViewById(R.id.btn_settlement);//去掉ExpandableListView 默认的箭头mExpandableListView.setGroupIndicator(null);//用于列表滑动时,EditText清除焦点,收起软键盘mExpandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView absListView, int scrollState) {if (SCROLL_STATE_TOUCH_SCROLL == scrollState) {InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);View focusView = getCurrentFocus();if (focusView != null) {inputMethodManager.hideSoftInputFromWindow(focusView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);focusView.clearFocus();}}}@Overridepublic void onScroll(AbsListView absListView, int i, int i1, int i2) {}});}

数据的话都是自己造的数据,存放在assets文件夹里面,下面是模拟网络请求数据并解析

private void initData() {//读取数据解析AssetManager assetManager = getAssets();try {InputStream is = assetManager.open("data.json");BufferedReader br = new BufferedReader(new InputStreamReader(is));stringBuffer = new StringBuffer();String str;while ((str = br.readLine()) != null) {stringBuffer.append(str);}} catch (IOException e) {e.printStackTrace();}Gson gson = new Gson();goodBean = gson.fromJson(stringBuffer.toString(), GoodBean.class);mAdapter = new ExpandableListAdapter(this, goodBean);mAdapter.setChangedListener(this);mExpandableListView.setAdapter(mAdapter);//展开所有的分组for (int i = 0; i < goodBean.getContent().size(); i++) {mExpandableListView.expandGroup(i);}}

模拟的json数据里面添加了店铺和商品是否被选中的标志字段,用来存放选中的状态。

适配器里面根据请求数据里面保存的状态设置店铺是否被选中:

@Overridepublic View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {GroupViewHolder holder;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.item_shopingcart_group, parent, false);holder = new GroupViewHolder(convertView);convertView.setTag(holder);} else {holder = (GroupViewHolder) convertView.getTag();}holder.cbGroupItem.setTag(groupPosition);holder.cbGroupItem.setOnClickListener(listener);holder.tvPosition.setText(goodBean.getContent().get(groupPosition).getAddress());//根据获取的状态设置是否被选中if (goodBean.getContent().get(groupPosition).isSelected()) {if (!holder.cbGroupItem.isChecked()) {holder.cbGroupItem.setChecked(true);}} else {holder.cbGroupItem.setChecked(false);}return convertView;}

头部布局的xml,这里使用了自定义的checkBox,点击选中的时候可以添加动画(具体代码看源码):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/white"android:orientation="vertical"><View
        android:layout_width="match_parent"android:layout_height="3dp"android:background="@color/divide_line" /><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:padding="15dp"><com.xp.shoppingcart.SmoothCheckBox
            android:id="@+id/cb_group_item"android:layout_width="24dp"android:layout_height="24dp" /><TextView
            android:id="@+id/tv_position"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:layout_weight="1"android:drawableLeft="@mipmap/ic_position"android:drawablePadding="3dp"android:text="京东旗舰店发货"android:textColor="#333333"android:textSize="15sp" /></LinearLayout>
</LinearLayout>

根据请求数据里面保存的状态设置店铺是否被选中:

@Overridepublic View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {ChildViewHolder holder;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.item_shopingcart_child, parent, false);holder = new ChildViewHolder(convertView);convertView.setTag(holder);} else {holder = (ChildViewHolder) convertView.getTag();}String tag = groupPosition + "," + childPosition;holder.cbItem.setTag(tag);holder.tvReduce.setTag(tag);holder.tvAdd.setTag(tag);holder.imgDelete.setTag(tag);holder.imgIcon.setTag(tag);holder.cbItem.setOnClickListener(listener);holder.tvReduce.setOnClickListener(listener);//添加商品数量holder.tvAdd.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {String tag = view.getTag().toString();String[] split;int groupId = 0;int childId = 0;int allCount = goodBean.getAllCount();int allMoney;if (tag.contains(",")) {split = tag.split(",");groupId = Integer.parseInt(split[0]);childId = Integer.parseInt(split[1]);}String goodCount = goodBean.getContent().get(groupId).getGoodDetail().get(childId).getCount();goodBean.getContent().get(groupId).getGoodDetail().get(childId).setCount(addCount(goodCount));allMoney = goodBean.getAllMoney();if (goodBean.getContent().get(groupId).getGoodDetail().get(childId).isSelected()) {allMoney += Integer.valueOf(goodBean.getContent().get(groupId).getGoodDetail().get(childId).getPrice());updateViewListener.update(goodBean.isAllSelect(), allCount, allMoney);}goodBean.setAllMoney(allMoney);notifyDataSetChanged();}});holder.imgDelete.setOnClickListener(listener);//根据获取的状态设置是否被选中if (goodBean.getContent().get(groupPosition).getGoodDetail().get(childPosition).isSelected()) {holder.cbItem.setChecked(true);} else {holder.cbItem.setChecked(false);}//设置数据holder.tvPrice.setText("¥" + goodBean.getContent().get(groupPosition).getGoodDetail().get(childPosition).getPrice());holder.tvGoodName.setText(goodBean.getContent().get(groupPosition).getGoodDetail().get(childPosition).getName());//对商品数量的监听EditTextWatcher textWatcher = (EditTextWatcher) holder.etCount.getTag(KEY_DATA);if (textWatcher != null) {holder.etCount.removeTextChangedListener(textWatcher);}holder.etCount.setText(String.valueOf(goodBean.getContent().get(groupPosition).getGoodDetail().get(childPosition).getCount()));EditTextWatcher watcher = new EditTextWatcher(goodBean.getContent().get(groupPosition).getGoodDetail().get(childPosition));holder.etCount.setTag(KEY_DATA, watcher);holder.etCount.addTextChangedListener(watcher);holder.etCount.setText(goodBean.getContent().get(groupPosition).getGoodDetail().get(childPosition).getCount());return convertView;}

每个商品的xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/white"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingRight="15dp"><LinearLayout
        android:id="@+id/ll_check"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:paddingLeft="15dp"android:paddingRight="17dp"><com.xp.shoppingcart.SmoothCheckBox
            android:id="@+id/cb_item"android:layout_width="24dp"android:layout_height="24dp"android:layout_gravity="center_vertical" /></LinearLayout><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><View
            android:layout_width="match_parent"android:layout_height="1dp"android:background="@color/divide_line" /><LinearLayout
            android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:orientation="horizontal"><ImageView
                android:id="@+id/img_icon"android:layout_width="78dp"android:layout_height="78dp"android:src="@mipmap/ic_phone" /><RelativeLayout
                android:layout_width="0dp"android:layout_height="match_parent"android:layout_marginLeft="15dp"android:layout_marginTop="8dp"android:layout_weight="1"><TextView
                    android:id="@+id/tv_good_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="" /><TextView
                    android:id="@+id/tv_reduce"android:layout_width="30dp"android:layout_height="30dp"android:layout_below="@id/tv_good_name"android:layout_marginTop="6dp"android:background="@drawable/selector_shopping_cart_subtract"android:gravity="center"android:text="-"android:textColor="@color/text_666666"android:textSize="15sp" /><EditText
                    android:id="@+id/et_count"android:layout_width="49dp"android:layout_height="30dp"android:layout_alignTop="@+id/tv_reduce"android:layout_marginBottom="1dp"android:layout_toRightOf="@+id/tv_reduce"android:background="@drawable/bg_input_box"android:gravity="center"android:inputType="number"android:maxLength="6"android:text="1"android:textColor="@color/text_666666"android:textCursorDrawable="@null"android:textSize="12sp" /><TextView
                    android:id="@+id/tv_add"android:layout_width="30dp"android:layout_height="30dp"android:layout_alignTop="@+id/tv_reduce"android:layout_toRightOf="@id/et_count"android:background="@drawable/selector_shopping_cart_add"android:gravity="center"android:text="+"android:textColor="@color/text_666666"android:textSize="15sp" /><TextView
                    android:id="@+id/tv_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentLeft="true"android:layout_alignParentStart="true"android:text="¥899"android:textColor="#FE3824"android:textSize="13sp" /></RelativeLayout><LinearLayout
                android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="18dp"android:gravity="end"android:orientation="vertical"></LinearLayout><ImageView
                android:id="@+id/img_delete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginTop="5dp"android:src="@mipmap/icon_delete" /></LinearLayout></LinearLayout></LinearLayout>

这里是对店铺点击选中事件的处理:

case R.id.cb_group_item:checkBox = (SmoothCheckBox) v;//根据父checkbox的选中状态设置存储数据里面商品是否被选中goodBean.getContent().get(groupPosition).setIsSelected(!checkBox.isChecked());if (!checkBox.isChecked()) {for (int i = 0; i < childSize; i++) {if (!goodBean.getContent().get(groupPosition).getGoodDetail().get(i).isSelected()) {allCount++;goodBean.getContent().get(groupPosition).getGoodDetail().get(i).setIsSelected(!checkBox.isChecked());allMoney += Integer.valueOf(goodBean.getContent().get(groupPosition).getGoodDetail().get(i).getCount())* Integer.valueOf(goodBean.getContent().get(groupPosition).getGoodDetail().get(i).getPrice());}}} else {allCount -= childSize;for (int i = 0; i < childSize; i++) {goodBean.getContent().get(groupPosition).getGoodDetail().get(i).setIsSelected(!checkBox.isChecked());allMoney -= Integer.valueOf(goodBean.getContent().get(groupPosition).getGoodDetail().get(i).getCount())* Integer.valueOf(goodBean.getContent().get(groupPosition).getGoodDetail().get(i).getPrice());}}//父item选中的数量int fCount = 0;//判断是否所有的父item都被选中,决定全选按钮状态for (int i = 0; i < goodBean.getContent().size(); i++) {if (goodBean.getContent().get(i).isSelected()) {fCount++;}}if (fCount == goodBean.getContent().size()) {goodBean.setAllSelect(true);} else {goodBean.setAllSelect(false);}goodBean.setAllCount(allCount);goodBean.setAllMoney(allMoney);notifyDataSetChanged();updateViewListener.update(goodBean.isAllSelect(), allCount, allMoney);break;

接下来是对每个商品选中的处理:

case R.id.cb_item:checkBox = (SmoothCheckBox) v;int cCount = 0;//子item被选中的数量int fcCount = 0;//父item被选中的数量goodBean.getContent().get(groupId).getGoodDetail().get(childId).setIsSelected(!checkBox.isChecked());//遍历父item所有数据,统计被选中的item数量for (int i = 0; i < goodBean.getContent().get(groupId).getGoodDetail().size(); i++) {if (goodBean.getContent().get(groupId).getGoodDetail().get(i).isSelected()) {cCount++;}}//判断是否所有的子item都被选中,决定父item状态if (cCount == goodBean.getContent().get(groupId).getGoodDetail().size()) {goodBean.getContent().get(groupId).setIsSelected(true);} else {goodBean.getContent().get(groupId).setIsSelected(false);}//判断是否所有的父item都被选中,决定全选按钮状态for (int i = 0; i < goodBean.getContent().size(); i++) {if (goodBean.getContent().get(i).isSelected()) {fcCount++;}}if (fcCount == goodBean.getContent().size()) {goodBean.setAllSelect(true);} else {goodBean.setAllSelect(false);}//判断子item状态,更新结算总商品数和合计Moneyif (!checkBox.isChecked()) {allCount++;allMoney += Integer.valueOf(goodBean.getContent().get(groupId).getGoodDetail().get(childId).getCount())* Integer.valueOf(goodBean.getContent().get(groupId).getGoodDetail().get(childId).getPrice());} else {allCount--;allMoney -= Integer.valueOf(goodBean.getContent().get(groupId).getGoodDetail().get(childId).getCount())* Integer.valueOf(goodBean.getContent().get(groupId).getGoodDetail().get(childId).getPrice());}goodBean.setAllCount(allCount);goodBean.setAllMoney(allMoney);notifyDataSetChanged();updateViewListener.update(goodBean.isAllSelect(), allCount, allMoney);break;

自定义回调接口更新显示的价格、数量:

/*** 更新数据的回调接口*/
public interface UpdateView {void update(boolean isAllSelected, int count, int price);
}

在主界面实现回调接口,更新数据:

@Overridepublic void update(boolean isAllSelected, int count, int price) {mBtnBuy.setText("结算(" + count + ")");mTvAllMoney.setText("¥" + price);mCbSelectAll.setChecked(isAllSelected);}

下载完整代码点击下边
源码Demo

Android实现淘宝购物车相关推荐

  1. Android 仿淘宝购物车实现

    功能基本和淘宝购物车一样,商品按照店铺分类显示,全选,反选,选中商品数量变化,总价随之变化.效果图 思路:店铺和商品都增加一个select属性,列表的CheckBox选择或未选中状态改变同时设置店铺和 ...

  2. Android仿淘宝购物车

    最近项目需要实现类似淘宝购物车的功能,仿了一个,直接上代码: public class MainActivity extends Activity implements OnCartListener, ...

  3. Android仿淘宝购物车demo

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 夏的热情 ...

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

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

  5. 仿淘宝购物车demo 增加和减少商品数量

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 在上一篇 ...

  6. 仿淘宝购物车demo---增加和减少商品数量

    在上一篇博客中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了 ...

  7. 高仿淘宝购物车分分钟让你集成

    前言 做商城类电商app购物车确实一直是一个难点,为什么难呢? 主要原因呢是他里面的逻辑复杂,然后 百度的资源好像都不太理想,好多就是一个简单的listView来实现根本就达不到开发的需求.然后 一般 ...

  8. 淘宝购物车分享上线第一天:630万人在用购物车社交

    来源 | 电商在线(ID:dianshangmj) 作者 | 吴羚玮 编辑|斯问 当一年中最大的消费季到来,很多人开始关心,"你的购物车里有什么". 网购时代,几乎每个人都有一辆「 ...

  9. 测试网页版淘宝购物车

    测试网页版淘宝购物车 界面测试: 1. 购物车页面布局是否合理,显示是否完整 2. 鼠标浮动在购物车图标,迷你购物车界面显示是否正常 3. 不同店铺的商品在不同的区域正确显示 4. 页面的菜单功能栏正 ...

  10. 使用python+selenium清空淘宝购物车

    selenium 概述 思路分析 1. 登录淘宝网 2. 输入用户名和密码 3. 访问购物车 4. 提交订单并确认支付 完整代码 概述 每当双十一等购物节到来的时候,我们经常需要熬夜到凌晨来对心仪的商 ...

最新文章

  1. 码分复用的matlab仿真,基于matlab的多路时分复用仿真.doc
  2. 不想被AI降维打击?美国“四院院士”写的DL科普书了解一下
  3. HDU——1418抱歉(平面欧拉公式)
  4. node:http协议、sql、接口
  5. 高密自智,体小量大,希捷Exos Corvault存储系统为数据洞察赋能
  6. Nginx学习之八-惊群问题
  7. 拳王虚拟项目公社:闲鱼虚拟资源玩法案例拆解,教你玩转虚拟资源,货源+方法
  8. php curl 发送checkbox,使用curl 提交表单(多维数组+文件)数据到服务器的有关问题...
  9. Win10,Win7,WinServer2012,WinServer2008内存最大支持
  10. Android文本输入框EditText方法说明和属性
  11. 哈弗h2s车内时间怎么调_你想拥抱的品质生活,就让哈弗H4乐享版帮你实现吧
  12. BigDecimal 使用浅析
  13. 在firefox 2.0.0.3中使用onenote 2007收集资料
  14. transition动画无效 iphone6
  15. 大小写字母的ASCII的对照转换
  16. HACCP认证咨询,食品生产过程中的主要危害是什么
  17. 怎么往日历里面加时钟java,怎样在博客里添加钟表和日历
  18. 手机助手+for+linux,你的手机助手(com.microsoft.appmanager) - 3.5.8 - 应用 - 酷安
  19. 二维动态规划降维误差一般为多少_数学建模常用算法模型
  20. 使用余弦相似度算法计算文本相似度

热门文章

  1. 标准二维表问题 (卡特兰数)
  2. 消元法解n元一次方程组 c++实现
  3. linux在文件夹压缩,在linux下如何将文件夹压缩成.tgz文件
  4. Python —— 压缩文件夹
  5. 文件系统 - 文件类型 - 二进制/文本类型
  6. 开机后黑屏看不到桌面_电脑开机后黑屏不显示桌面解决方法
  7. 图像scale与相机参数_摄像头参数测试指导分析解析
  8. metro,subway,tube这三个单词如何区分?
  9. 计算机辅助logo设计与实现,新手都会看的logo设计师53条规则
  10. 计算机网络是由网络硬件网络软件,计算机网络系统主要由网络硬件系统和网络软件系统组成。...