Android购物车的实现(升级版 仿淘宝)

转自: http://blog.csdn.net/u014061684/article/details/50608588


前面有篇文章实现了Android 简单的购物车 这篇实现了购物车中商品按照店铺分类显示的 也就是淘宝购物车的显示方式。











主要代码

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.jock.shopcart;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import android.app.Activity;  
  9. import android.app.AlertDialog;  
  10. import android.content.Context;  
  11. import android.content.DialogInterface;  
  12. import android.os.Bundle;  
  13. import android.view.View;  
  14. import android.view.View.OnClickListener;  
  15. import android.view.Window;  
  16. import android.widget.CheckBox;  
  17. import android.widget.ExpandableListView;  
  18. import android.widget.TextView;  
  19. import android.widget.Toast;  
  20.   
  21. import com.jock.adapter.ShopcartExpandableListViewAdapter;  
  22. import com.jock.adapter.ShopcartExpandableListViewAdapter.CheckInterface;  
  23. import com.jock.adapter.ShopcartExpandableListViewAdapter.ModifyCountInterface;  
  24. import com.jock.entity.GroupInfo;  
  25. import com.jock.entity.ProductInfo;  
  26. import com.jock.shopcar.R;  
  27.   
  28. public class MainActivity extends Activity implements CheckInterface, ModifyCountInterface, OnClickListener  
  29. {  
  30.     private ExpandableListView exListView;  
  31.     private CheckBox cb_check_all;  
  32.     private TextView tv_total_price;  
  33.     private TextView tv_delete;  
  34.     private TextView tv_go_to_pay;  
  35.     private Context context;  
  36.   
  37.     private double totalPrice = 0.00;// 购买的商品总价  
  38.     private int totalCount = 0;// 购买的商品总数量  
  39.   
  40.     private ShopcartExpandableListViewAdapter selva;  
  41.     private List<GroupInfo> groups = new ArrayList<GroupInfo>();// 组元素数据列表  
  42.     private Map<String, List<ProductInfo>> children = new HashMap<String, List<ProductInfo>>();// 子元素数据列表  
  43.   
  44.     @Override  
  45.     protected void onCreate(Bundle savedInstanceState)  
  46.     {  
  47.         super.onCreate(savedInstanceState);  
  48.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  49.         setContentView(R.layout.activity_main);  
  50.   
  51.         initView();  
  52.         initEvents();  
  53.     }  
  54.   
  55.     private void initView()  
  56.     {  
  57.         context = this;  
  58.         virtualData();  
  59.         exListView = (ExpandableListView) findViewById(R.id.exListView);  
  60.         cb_check_all = (CheckBox) findViewById(R.id.all_chekbox);  
  61.         tv_total_price = (TextView) findViewById(R.id.tv_total_price);  
  62.         tv_delete = (TextView) findViewById(R.id.tv_delete);  
  63.         tv_go_to_pay = (TextView) findViewById(R.id.tv_go_to_pay);  
  64.     }  
  65.   
  66.     private void initEvents()  
  67.     {  
  68.         selva = new ShopcartExpandableListViewAdapter(groups, children, this);  
  69.         selva.setCheckInterface(this);// 关键步骤1,设置复选框接口  
  70.         selva.setModifyCountInterface(this);// 关键步骤2,设置数量增减接口  
  71.         exListView.setAdapter(selva);  
  72.   
  73.         for (int i = 0; i < selva.getGroupCount(); i++)  
  74.         {  
  75.             exListView.expandGroup(i);// 关键步骤3,初始化时,将ExpandableListView以展开的方式呈现  
  76.         }  
  77.   
  78.         cb_check_all.setOnClickListener(this);  
  79.         tv_delete.setOnClickListener(this);  
  80.         tv_go_to_pay.setOnClickListener(this);  
  81.     }  
  82.   
  83.     /** 
  84.      * 模拟数据<br> 
  85.      * 遵循适配器的数据列表填充原则,组元素被放在一个List中,对应的组元素下辖的子元素被放在Map中,<br> 
  86.      * 其键是组元素的Id(通常是一个唯一指定组元素身份的值) 
  87.      */  
  88.     private void virtualData()  
  89.     {  
  90.   
  91.         for (int i = 0; i < 6; i++)  
  92.         {  
  93.   
  94.             groups.add(new GroupInfo(i + """第八号当铺" + (i + 1) + "号店"));  
  95.   
  96.             List<ProductInfo> products = new ArrayList<ProductInfo>();  
  97.             for (int j = 0; j <= i; j++)  
  98.             {  
  99.   
  100.                 products.add(new ProductInfo(j + """商品""", groups.get(i).getName() + "的第" + (j + 1) + "个商品"120.00 + i * j, 1));  
  101.             }  
  102.             children.put(groups.get(i).getId(), products);// 将组元素的一个唯一值,这里取Id,作为子元素List的Key  
  103.         }  
  104.     }  
  105.   
  106.     @Override  
  107.     public void onClick(View v)  
  108.     {  
  109.         AlertDialog alert;  
  110.         switch (v.getId())  
  111.         {  
  112.         case R.id.all_chekbox:  
  113.             doCheckAll();  
  114.             break;  
  115.         case R.id.tv_go_to_pay:  
  116.             if (totalCount == 0)  
  117.             {  
  118.                 Toast.makeText(context, "请选择要支付的商品", Toast.LENGTH_LONG).show();  
  119.                 return;  
  120.             }  
  121.             alert = new AlertDialog.Builder(context).create();  
  122.             alert.setTitle("操作提示");  
  123.             alert.setMessage("总计:\n" + totalCount + "种商品\n" + totalPrice + "元");  
  124.             alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消"new DialogInterface.OnClickListener()  
  125.             {  
  126.                 @Override  
  127.                 public void onClick(DialogInterface dialog, int which)  
  128.                 {  
  129.                     return;  
  130.                 }  
  131.             });  
  132.             alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定"new DialogInterface.OnClickListener()  
  133.             {  
  134.                 @Override  
  135.                 public void onClick(DialogInterface dialog, int which)  
  136.                 {  
  137.                     return;  
  138.                 }  
  139.             });  
  140.             alert.show();  
  141.             break;  
  142.         case R.id.tv_delete:  
  143.             if (totalCount == 0)  
  144.             {  
  145.                 Toast.makeText(context, "请选择要移除的商品", Toast.LENGTH_LONG).show();  
  146.                 return;  
  147.             }  
  148.             alert = new AlertDialog.Builder(context).create();  
  149.             alert.setTitle("操作提示");  
  150.             alert.setMessage("您确定要将这些商品从购物车中移除吗?");  
  151.             alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消"new DialogInterface.OnClickListener()  
  152.             {  
  153.                 @Override  
  154.                 public void onClick(DialogInterface dialog, int which)  
  155.                 {  
  156.                     return;  
  157.                 }  
  158.             });  
  159.             alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定"new DialogInterface.OnClickListener()  
  160.             {  
  161.                 @Override  
  162.                 public void onClick(DialogInterface dialog, int which)  
  163.                 {  
  164.                     doDelete();  
  165.                 }  
  166.             });  
  167.             alert.show();  
  168.             break;  
  169.         }  
  170.     }  
  171.   
  172.     /** 
  173.      * 删除操作<br> 
  174.      * 1.不要边遍历边删除,容易出现数组越界的情况<br> 
  175.      * 2.现将要删除的对象放进相应的列表容器中,待遍历完后,以removeAll的方式进行删除 
  176.      */  
  177.     protected void doDelete()  
  178.     {  
  179.         List<GroupInfo> toBeDeleteGroups = new ArrayList<GroupInfo>();// 待删除的组元素列表  
  180.         for (int i = 0; i < groups.size(); i++)  
  181.         {  
  182.             GroupInfo group = groups.get(i);  
  183.             if (group.isChoosed())  
  184.             {  
  185.   
  186.                 toBeDeleteGroups.add(group);  
  187.             }  
  188.             List<ProductInfo> toBeDeleteProducts = new ArrayList<ProductInfo>();// 待删除的子元素列表  
  189.             List<ProductInfo> childs = children.get(group.getId());  
  190.             for (int j = 0; j < childs.size(); j++)  
  191.             {  
  192.                 if (childs.get(j).isChoosed())  
  193.                 {  
  194.                     toBeDeleteProducts.add(childs.get(j));  
  195.                 }  
  196.             }  
  197.             childs.removeAll(toBeDeleteProducts);  
  198.   
  199.         }  
  200.   
  201.         groups.removeAll(toBeDeleteGroups);  
  202.   
  203.         selva.notifyDataSetChanged();  
  204.         calculate();  
  205.     }  
  206.   
  207.     @Override  
  208.     public void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked)  
  209.     {  
  210.   
  211.         ProductInfo product = (ProductInfo) selva.getChild(groupPosition, childPosition);  
  212.         int currentCount = product.getCount();  
  213.         currentCount++;  
  214.         product.setCount(currentCount);  
  215.         ((TextView) showCountView).setText(currentCount + "");  
  216.   
  217.         selva.notifyDataSetChanged();  
  218.         calculate();  
  219.     }  
  220.   
  221.     @Override  
  222.     public void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked)  
  223.     {  
  224.   
  225.         ProductInfo product = (ProductInfo) selva.getChild(groupPosition, childPosition);  
  226.         int currentCount = product.getCount();  
  227.         if (currentCount == 1)  
  228.             return;  
  229.         currentCount--;  
  230.   
  231.         product.setCount(currentCount);  
  232.         ((TextView) showCountView).setText(currentCount + "");  
  233.   
  234.         selva.notifyDataSetChanged();  
  235.         calculate();  
  236.     }  
  237.   
  238.     @Override  
  239.     public void checkGroup(int groupPosition, boolean isChecked)  
  240.     {  
  241.         GroupInfo group = groups.get(groupPosition);  
  242.         List<ProductInfo> childs = children.get(group.getId());  
  243.         for (int i = 0; i < childs.size(); i++)  
  244.         {  
  245.             childs.get(i).setChoosed(isChecked);  
  246.         }  
  247.         if (isAllCheck())  
  248.             cb_check_all.setChecked(true);  
  249.         else  
  250.             cb_check_all.setChecked(false);  
  251.         selva.notifyDataSetChanged();  
  252.         calculate();  
  253.     }  
  254.   
  255.     @Override  
  256.     public void checkChild(int groupPosition, int childPosiTion, boolean isChecked)  
  257.     {  
  258.         boolean allChildSameState = true;// 判断改组下面的所有子元素是否是同一种状态  
  259.         GroupInfo group = groups.get(groupPosition);  
  260.         List<ProductInfo> childs = children.get(group.getId());  
  261.         for (int i = 0; i < childs.size(); i++)  
  262.         {  
  263.             if (childs.get(i).isChoosed() != isChecked)  
  264.             {  
  265.                 allChildSameState = false;  
  266.                 break;  
  267.             }  
  268.         }  
  269.         if (allChildSameState)  
  270.         {  
  271.             group.setChoosed(isChecked);// 如果所有子元素状态相同,那么对应的组元素被设为这种统一状态  
  272.         } else  
  273.         {  
  274.             group.setChoosed(false);// 否则,组元素一律设置为未选中状态  
  275.         }  
  276.   
  277.         if (isAllCheck())  
  278.             cb_check_all.setChecked(true);  
  279.         else  
  280.             cb_check_all.setChecked(false);  
  281.         selva.notifyDataSetChanged();  
  282.         calculate();  
  283.     }  
  284.   
  285.     private boolean isAllCheck()  
  286.     {  
  287.   
  288.         for (GroupInfo group : groups)  
  289.         {  
  290.             if (!group.isChoosed())  
  291.                 return false;  
  292.   
  293.         }  
  294.   
  295.         return true;  
  296.     }  
  297.   
  298.     /** 全选与反选 */  
  299.     private void doCheckAll()  
  300.     {  
  301.         for (int i = 0; i < groups.size(); i++)  
  302.         {  
  303.             groups.get(i).setChoosed(cb_check_all.isChecked());  
  304.             GroupInfo group = groups.get(i);  
  305.             List<ProductInfo> childs = children.get(group.getId());  
  306.             for (int j = 0; j < childs.size(); j++)  
  307.             {  
  308.                 childs.get(j).setChoosed(cb_check_all.isChecked());  
  309.             }  
  310.         }  
  311.         selva.notifyDataSetChanged();  
  312.     }  
  313.   
  314.     /** 
  315.      * 统计操作<br> 
  316.      * 1.先清空全局计数器<br> 
  317.      * 2.遍历所有子元素,只要是被选中状态的,就进行相关的计算操作<br> 
  318.      * 3.给底部的textView进行数据填充 
  319.      */  
  320.     private void calculate()  
  321.     {  
  322.         totalCount = 0;  
  323.         totalPrice = 0.00;  
  324.         for (int i = 0; i < groups.size(); i++)  
  325.         {  
  326.             GroupInfo group = groups.get(i);  
  327.             List<ProductInfo> childs = children.get(group.getId());  
  328.             for (int j = 0; j < childs.size(); j++)  
  329.             {  
  330.                 ProductInfo product = childs.get(j);  
  331.                 if (product.isChoosed())  
  332.                 {  
  333.                     totalCount++;  
  334.                     totalPrice += product.getPrice() * product.getCount();  
  335.                 }  
  336.             }  
  337.         }  
  338.         tv_total_price.setText("¥" + totalPrice);  
  339.         tv_go_to_pay.setText("去支付(" + totalCount + ")");  
  340.     }  
  341. }  

源码下载



修订版本源码下载

阅读更多
换一批

没有更多推荐了,返回首页