Android实现淘宝购物车
来源:互联网 发布:php医院预约挂号源码 编辑:程序博客网 时间:2024/04/27 22:44
先上效果:
购物车实现使用的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() { @Override public 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(); } } } @Override public 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数据里面添加了店铺和商品是否被选中的标志字段,用来存放选中的状态。
适配器里面根据请求数据里面保存的状态设置店铺是否被选中:
@Override public 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>
根据请求数据里面保存的状态设置店铺是否被选中:
@Override public 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() { @Override public 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状态,更新结算总商品数和合计Money if (!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);}
在主界面实现回调接口,更新数据:
@Override public void update(boolean isAllSelected, int count, int price) { mBtnBuy.setText("结算(" + count + ")"); mTvAllMoney.setText("¥" + price); mCbSelectAll.setChecked(isAllSelected); }
下载完整代码点击下边
源码Demo
阅读全文
2 0
- Android实现淘宝购物车
- 实现淘宝购物车功能
- Android仿淘宝购物车
- Android仿淘宝购物车
- Android仿淘宝购物车
- Android购物车的实现(升级版 仿淘宝)
- Android购物车的实现(升级版 仿淘宝)
- 【Android动画】仿淘宝加入购物车动画实现
- 仿淘宝购物车的实现
- 淘宝购物车功能的实现
- Android仿淘宝购物车demo
- Android-ExpandableListView 仿京东淘宝购物车
- Android一点 仿淘宝购物车动画
- Android 购物车 高仿淘宝
- Android仿淘宝购物车,玩转电商购物车
- Android动画初探-实现淘宝加入加入购物车的效果
- Android开发之浅谈仿淘宝购物车实现(一)
- Android电商项目 ExpandableListView(二级列表)实现购物车(高仿淘宝) demo
- js类型判断全集
- 高并发MPP查询引擎Impala初识
- KCF跟踪算法代码摘要
- Mybatis的动态sql标签
- Windows 10如何配置本地WAMPSERVER测试环
- Android实现淘宝购物车
- Node.js入门小记(三)Api之URL
- 《Linux内核设计与实现》读书笔记(一)-内核简介
- python面试 -- 数字篇
- 第一天-HelloWorld
- 在使用recyclerview出现的Error:Could not find com.android.support:recyclerview-v7:25.3.1-alpha1. Required b
- CSS中margin-top对父级元素产生作用的问题
- Android Studio如何查看branch列表及切换branch
- HDFS 架构