前言
购物车系列文章:
购物车列表及确认订单页面 - 技术分析(一)
购物车列表及确认订单页面 - 相关代码(二)
购物车列表及确认订单页面 - 相关代码(三)
购物车列表及确认订单页面 - 部分知识点思路解析(四)
1. 代码如下
1>:主界面Activity:
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/10/6 10:15
* Version 1.0
* Params:
* Description: 购物车 - 店铺及商品
*/
public class ELongActivity extends AppCompatActivity implements View.OnClickListener, ShopcatAdapter.CheckInterface, ShopcatAdapter.ModifyCountInterface, ShopcatAdapter.GroupEditorListener{
@BindView(R.id.all_checkBox)
CheckBox allCheckBox;
@BindView(R.id.total_price)
TextView totalPrice;
@BindView(R.id.go_pay)
TextView goPay;
@BindView(R.id.order_info)
LinearLayout orderInfo;
@BindView(R.id.share_goods)
TextView shareGoods;
@BindView(R.id.collect_goods)
TextView collectGoods;
@BindView(R.id.del_goods)
TextView delGoods;
@BindView(R.id.share_info)
LinearLayout shareInfo;
@BindView(R.id.ll_cart)
LinearLayout llCart;
/*@BindView(R.id.mPtrframe)
PtrFrameLayout mPtrFrame;*/
TextView shoppingcatNum;
Button actionBarEdit;
LinearLayout empty_shopcart;
private double mtotalPrice = 0.00;
private int mtotalCount = 0;
//false就是编辑,ture就是完成
private boolean flag = false;
private SExpandableListView expandableListView;
private Context mcontext;
// 所有組的集合
private List<MiddleBean.StoreInfo> groups2 = new ArrayList<MiddleBean.StoreInfo>();
// 所有子元素的集合
private Map<String, List<MiddleBean.StoreInfo.GoodsInfo>> childs2 = new HashMap<String, List<MiddleBean.StoreInfo.GoodsInfo>>();;
private ShopcatAdapter adapter;
// 加载的个数
private int loadCount;
private boolean isPull;
private Handler handler = new Handler() {
@Override
public void handleMessage(android.os.Message msg) {
/*// 刷新完成
if (loadCount > 6) {
expandableListView.refreshComplete();
expandableListView.setNoMore(true);
} else {
// 加载更多
addLoadMoreData();
if (isPull) {
expandableListView.refreshComplete();
}
adapter.notifyDataSetChanged();
// expanedAll();
}*/
// Log.e("TAG---收到消息:", loadCount + "-->");
switch (msg.what){
case 1:
expandableListView.refreshComplete();
expandableListView.setNoMore(true);
// 刷新时先清空外层集合
groups2.clear();
childs2.clear();
// 请求刷新的数据
refreshData();
// 然后重新给外层集合设置数据
groups2.addAll(groups);
childs2.putAll(childs);
//关键步骤:初始化,将ExpandableListView以展开的方式显示
for (int i = 0; i < adapter.getGroupCount(); i++) {
expandableListView.expandGroup(i);
}
adapter.notifyDataSetChanged();
break;
case 2:
// 加载更多
loadData();
// 给外层总的集合设置数据
groups2.addAll(groups);
childs2.putAll(childs);
if (isPull) {
expandableListView.refreshComplete();
}
//关键步骤:初始化,将ExpandableListView以展开的方式显示
for (int i = 0; i < adapter.getGroupCount(); i++) {
expandableListView.expandGroup(i);
}
adapter.notifyDataSetChanged();
break;
}
}
};
private List<MiddleBean.StoreInfo> groups;
private Map<String, List<MiddleBean.StoreInfo.GoodsInfo>> childs;
private int count;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_elong_explandlv);
ButterKnife.bind(this);
initView();
// 标题栏
initActionBar();
// 模拟数据
initData();
initEvent() ;
}
private void initActionBar() {
//隐藏标题栏
if (getSupportActionBar() != null) {
//去掉阴影
getSupportActionBar().setElevation(0);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowCustomEnabled(true);
View view = getLayoutInflater().inflate(R.layout.acitonbar, null);
findView(view);
getSupportActionBar().setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
ActionBar.LayoutParams lp = (ActionBar.LayoutParams) view.getLayoutParams();
lp.gravity = Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.CENTER_HORIZONTAL;
getSupportActionBar().setCustomView(view, lp);
}
}
private void findView(View view) {
shoppingcatNum = (TextView) view.findViewById(R.id.shoppingcat_num);
// 右上角编辑
actionBarEdit = (Button) view.findViewById(R.id.actionBar_edit);
//不知道为什么,ButterKnife不知道BindView
empty_shopcart = (LinearLayout) findViewById(R.id.layout_empty_shopcart);
}
@Override
protected void onResume() {
super.onResume();
setCartNum();
}
/**
* 设置购物车的数量
*/
private void setCartNum() {
int count = 0;
for (int i = 0; i < groups2.size(); i++) { // groups
MiddleBean.StoreInfo group = groups2.get(i); // groups
group.setChoosed(allCheckBox.isChecked());
List<MiddleBean.StoreInfo.GoodsInfo> Childs = childs2.get(group.getId()); // childs
for (MiddleBean.StoreInfo.GoodsInfo childs : Childs) {
count++;
}
}
//购物车已经清空
if (count == 0) {
clearCart();
} else {
shoppingcatNum.setText("共有" + count + "件商品");
}
}
private void clearCart() {
shoppingcatNum.setText("共有" + 0 + "件商品");
actionBarEdit.setVisibility(View.GONE);
llCart.setVisibility(View.GONE);
empty_shopcart.setVisibility(View.VISIBLE);//这里发生过错误
}
/**
* 删除操作
* 1.不要边遍历边删除,容易出现数组越界的情况
* 2.把将要删除的对象放进相应的容器中,待遍历完,用removeAll的方式进行删除
*/
private void doDelete() {
List<MiddleBean.StoreInfo> toBeDeleteGroups = new ArrayList<MiddleBean.StoreInfo>(); //待删除的组元素
for (int i = 0; i < groups2.size(); i++) { // groups
MiddleBean.StoreInfo group = groups2.get(i); // groups
if (group.isChoosed()) {
toBeDeleteGroups.add(group);
}
List<MiddleBean.StoreInfo.GoodsInfo> toBeDeleteChilds = new ArrayList<MiddleBean.StoreInfo.GoodsInfo>();//待删除的子元素
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId()); // childs
for (int j = 0; j < child.size(); j++) {
if (child.get(j).isChoosed()) {
toBeDeleteChilds.add(child.get(j));
}
}
child.removeAll(toBeDeleteChilds);
}
groups2.removeAll(toBeDeleteGroups); // groups
//重新设置购物车
setCartNum();
adapter.notifyDataSetChanged();
}
/**
* @param groupPosition 组元素的位置
* @param isChecked 组元素的选中与否
* 思路:组元素被选中了,那么下辖全部的子元素也被选中
*/
@Override
public void checkGroup(int groupPosition, boolean isChecked) {
MiddleBean.StoreInfo group = groups2.get(groupPosition); // groups
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId()); // childs
for (int i = 0; i < child.size(); i++) {
child.get(i).setChoosed(isChecked);
}
if (isCheckAll()) {
allCheckBox.setChecked(true);//全选
} else {
allCheckBox.setChecked(false);//反选
}
adapter.notifyDataSetChanged();
calulate();
}
/**
* @return 判断组元素是否全选
*/
private boolean isCheckAll() {
for (MiddleBean.StoreInfo group : groups2) { // groups
if (!group.isChoosed()) {
return false;
}
}
return true;
}
/**
* @param groupPosition 组元素的位置
* @param childPosition 子元素的位置
* @param isChecked 子元素的选中与否
*/
@Override
public void checkChild(int groupPosition, int childPosition, boolean isChecked) {
boolean allChildSameState = true; //判断该组下面的所有子元素是否处于同一状态
MiddleBean.StoreInfo group = groups2.get(groupPosition); // groups
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId()); // childs
for (int i = 0; i < child.size(); i++) {
//不选全中
if (child.get(i).isChoosed() != isChecked) {
allChildSameState = false;
break;
}
}
if (allChildSameState) {
group.setChoosed(isChecked);//如果子元素状态相同,那么对应的组元素也设置成这一种的同一状态
} else {
group.setChoosed(false);//否则一律视为未选中
}
if (isCheckAll()) {
allCheckBox.setChecked(true);//全选
} else {
allCheckBox.setChecked(false);//反选
}
adapter.notifyDataSetChanged();
calulate();
}
/**
* 点击加号,然后给数量设置数据的回调
*
* @param groupPosition 组元素的位置
* @param childPosition 子元素的位置
* @param showCountView 用于展示变化后数量的View
* @param isChecked 子元素选中与否
*/
@Override
public void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked) {
MiddleBean.StoreInfo.GoodsInfo good = (MiddleBean.StoreInfo.GoodsInfo) adapter.getChild(groupPosition, childPosition);
// 从实体类中获取数量
count = good.getCount();
// 点击加号,让 count加加
count++;
// 并且把 count设置给 实体类
good.setCount(count);
// 同时给加号和减号中间的数量设置 count
((TextView) showCountView).setText(String.valueOf(count));
adapter.notifyDataSetChanged();
calulate();
}
/**
* 点击减号,然后给数量设置数据的回调
*
* @param groupPosition
* @param childPosition
* @param showCountView
* @param isChecked
*/
@Override
public void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked) {
MiddleBean.StoreInfo.GoodsInfo good = (MiddleBean.StoreInfo.GoodsInfo) adapter.getChild(groupPosition, childPosition);
// 从实体类中获取数量
count = good.getCount();
// 作如下判断:
// 如果 count等于1,点击减号就不要再让数字往下减了
if (count == 1) {
return;
}
// 如果 count大于1,点击减号就让数量减减
if (count >= 1) {
count--;
}else{
return;
}
// 然后把变化后的 count 设置给实体类good
good.setCount(count);
// 并且给加号和减号中间的数量设置数据
((TextView) showCountView).setText("" + count);
// 通知adapter刷新
adapter.notifyDataSetChanged();
// 重新统计
calulate();
}
/**
* @param groupPosition
* @param childPosition 思路:当子元素=0,那么组元素也要删除
*/
@Override
public void childDelete(int groupPosition, int childPosition) {
MiddleBean.StoreInfo group = groups2.get(groupPosition); // groups
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId()); // childs
child.remove(childPosition);
if (child.size() == 0) {
groups2.remove(groupPosition); // groups
}
adapter.notifyDataSetChanged();
calulate();
}
/**
* 编辑数量后更新数量
*/
public void doUpdate(int groupPosition, int childPosition, View showCountView, boolean isChecked) {
MiddleBean.StoreInfo.GoodsInfo good = (MiddleBean.StoreInfo.GoodsInfo) adapter.getChild(groupPosition, childPosition);
// 从实体类中获取数量count
count = good.getCount();
UtilsLog.i("进行更新数据,数量" + count + "");
// 设置给加号和减号中间的数量
((TextView) showCountView).setText(String.valueOf(count));
adapter.notifyDataSetChanged();
calulate();
}
@Override
public void groupEditor(int groupPosition) {
}
@OnClick({R.id.all_checkBox, R.id.go_pay, R.id.share_goods, R.id.collect_goods, R.id.del_goods})
public void onClick(View view) {
AlertDialog dialog;
switch (view.getId()) {
case R.id.all_checkBox:
doCheckAll();
break;
case R.id.go_pay:
if (mtotalCount == 0) {
UtilTool.toast(mcontext, "请选择要支付的商品");
return;
}
dialog = new AlertDialog.Builder(mcontext).create();
dialog.setMessage("总计:" + mtotalCount + "种商品," + mtotalPrice + "元");
dialog.setButton(DialogInterface.BUTTON_POSITIVE, "支付", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
goToPay() ;
return;
}
});
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
return;
}
});
dialog.show();
break;
case R.id.share_goods:
if (mtotalCount == 0) {
UtilTool.toast(mcontext, "请选择要分享的商品");
return;
}
UtilTool.toast(mcontext, "分享成功");
break;
case R.id.collect_goods:
if (mtotalCount == 0) {
UtilTool.toast(mcontext, "请选择要收藏的商品");
return;
}
UtilTool.toast(mcontext, "收藏成功");
break;
case R.id.del_goods:
if (mtotalCount == 0) {
UtilTool.toast(mcontext, "请选择要删除的商品");
return;
}
dialog = new AlertDialog.Builder(mcontext).create();
dialog.setMessage("确认要删除该商品吗?");
dialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
doDelete();
}
});
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
return;
}
});
dialog.show();
break;
// 点击右上角编辑
case R.id.actionBar_edit:
flag = !flag;
setActionBarEditor();
setVisiable();
break;
}
}
// 选中的组集合(不一定选中了组,只要选中该组下的商品,就把该商品对应的组添加进来)
private List<MiddleBean.StoreInfo> toPayGroups ;
// 选中的去重之后的组集合
private List<MiddleBean.StoreInfo> list;
// 选中的子集合
private List<MiddleBean.StoreInfo.GoodsInfo> toPayChilds ;
private void goToPay() {
toPayGroups = new ArrayList<MiddleBean.StoreInfo>();
list = new ArrayList<MiddleBean.StoreInfo>() ;
// 遍历所有组的集合
for (int i = 0; i < groups2.size(); i++) {
// 获取到每一个组
MiddleBean.StoreInfo group = groups2.get(i);
// 从所有子元素集合中 根据每个组的id 取出该组 对应的子元素集合
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId());
// TODO: ------------- 这个商品的集合必须放到遍历店铺集合的里边,必须注意!!! ------------ //
// 选中的商品集合
toPayChilds = new ArrayList<MiddleBean.StoreInfo.GoodsInfo>();
toPayChilds.clear();
// 遍历每个子元素的集合
for (int j = 0; j < child.size(); j++) {
// 如果子元素被选中,并且该子元素中的店铺id等于该组中的店铺id
if (child.get(j).isChoosed() && child.get(j).getStroeId().equals(group.getId())) {
// 就把选中的商品添加到商品toPayChilds集合中
toPayChilds.add(child.get(j));
// 然后把toPayChilds设置给 该店铺下的 group.setGoodses
group.setGoodses(toPayChilds);
// 然后把每个店铺的实体group:放到放到店铺集合
toPayGroups.add(group);
}
}
}
// 然后给店铺的集合去重
list = removeDuplicate(toPayGroups);
/*for (int i = 0; i < list.size(); i++) {
List<MiddleBean.StoreInfo.GoodsInfo> goodses = list.get(i).getGoodses();
for (int j = 0; j < goodses.size(); j++) {
int count = goodses.get(j).getCount();
Log.e("TAG" , "遍历集合后的数量:"+count) ;
}
}*/
// 可以直接用这个list给 在确认订单页面给店铺及对应的子元素设置数据
Intent intent = new Intent(ELongActivity.this, GoPayCartActivity.class) ;
intent.putExtra("listConfirm", (Serializable) list);
startActivity(intent);
}
/**
* list集合去重
*/
public List removeDuplicate(List<MiddleBean.StoreInfo> list){
List<MiddleBean.StoreInfo> listTemp = new ArrayList();
for(int i=0;i<list.size();i++){
if(!listTemp.contains(list.get(i))){
listTemp.add(list.get(i));
}
}
return listTemp;
}
/**
* ActionBar标题上点编辑的时候,只显示每一个店铺的商品修改界面
* ActionBar标题上点完成的时候,只显示每一个店铺的商品信息界面
*/
private void setActionBarEditor() {
for (int i = 0; i < groups2.size(); i++) { // groups
MiddleBean.StoreInfo group = groups2.get(i); // groups
if (group.isActionBarEditor()) {
group.setActionBarEditor(false);
} else {
group.setActionBarEditor(true);
}
}
adapter.notifyDataSetChanged();
}
/**
* 全选和反选
* 错误标记:在这里出现过错误
*/
private void doCheckAll() {
for (int i = 0; i < groups2.size(); i++) { // groups
MiddleBean.StoreInfo group = groups2.get(i); // groups
group.setChoosed(allCheckBox.isChecked());
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId()); // childs
for (int j = 0; j < child.size(); j++) {
child.get(j).setChoosed(allCheckBox.isChecked());//这里出现过错误
}
}
adapter.notifyDataSetChanged();
calulate();
}
/**
* 计算商品总价格,操作步骤
* 1.先清空全局计价,计数
* 2.遍历所有的子元素,只要是被选中的,就进行相关的计算操作
* 3.给textView填充数据
*/
private void calulate() {
mtotalPrice = 0.00;
mtotalCount = 0;
for (int i = 0; i < groups2.size(); i++) { // groups
MiddleBean.StoreInfo group = groups2.get(i); // groups
List<MiddleBean.StoreInfo.GoodsInfo> child = childs2.get(group.getId()); // childs
for (int j = 0; j < child.size(); j++) {
MiddleBean.StoreInfo.GoodsInfo good = child.get(j);
if (good.isChoosed()) {
mtotalCount++;
mtotalPrice += good.getPrice() * good.getCount();
}
}
}
totalPrice.setText("¥" + mtotalPrice + "");
goPay.setText("去支付(" + mtotalCount + ")");
if (mtotalCount == 0) {
setCartNum();
} else {
shoppingcatNum.setText("共有" + mtotalCount + "件商品");
}
}
private void setVisiable() {
if (flag) {
orderInfo.setVisibility(View.GONE);
shareInfo.setVisibility(View.VISIBLE);
actionBarEdit.setText("完成");
} else {
orderInfo.setVisibility(View.VISIBLE);
shareInfo.setVisibility(View.GONE);
actionBarEdit.setText("编辑");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
adapter = null;
childs2.clear(); // childs
groups2.clear(); // groups
mtotalPrice = 0.00;
mtotalCount = 0;
Log.e("TAG" , "onDestroy: "+", adapter:"+adapter+", groups2: "+groups2.size()+", childs2: "+childs2.size()) ;
}
private void initEvent() {
actionBarEdit.setOnClickListener(this);
// 店铺集合数据,店铺对应商品集合数据
adapter = new ShopcatAdapter(groups2, childs2, mcontext);
adapter.setCheckInterface(this); //关键步骤1:设置复选框的接口
adapter.setModifyCountInterface(this); //关键步骤2:设置增删减的接口
adapter.setGroupEditorListener(this); //关键步骤3:监听组列表的编辑状态
// 在设置适配器之前设置是否支持下拉刷新
expandableListView.setLoadingMoreEnabled(true);
expandableListView.setPullRefreshEnabled(true);
expandableListView.setGroupIndicator(null);
expandableListView.setAdapter(adapter);
for (int i = 0; i < adapter.getGroupCount(); i++) {
expandableListView.expandGroup(i); //关键步骤4:初始化,将ExpandableListView以展开的方式显示
}
expandableListView.setmLoadingListener(new SExpandableListView.LoadingListener() {
/**
* 下拉刷新
*/
@Override
public void onRefresh() {
isPull = true;
handler.sendEmptyMessage(1);
/*isPull = true;
loadCount++;
Message msg = handler.obtainMessage();
msg.arg1 = loadCount;
handler.sendMessageDelayed(msg, 2000);
Log.e("TAG---HANDLER:", loadCount + "-->");*/
}
/**
* 上拉加载更多
*/
@Override
public void onLoadMore() {
isPull = false;
handler.sendEmptyMessage(2);
/*isPull = false;
loadCount++;
Message msg = handler.obtainMessage();
msg.arg1 = loadCount;
handler.sendMessageDelayed(msg, 2000);
Log.e("TAG---HANDLER:", loadCount + "-->");*/
}
});
}
/**
* 此处用于测试刷新
*/
private void refreshData() {
mcontext = this;
// 店铺信息集合
groups = new ArrayList<MiddleBean.StoreInfo>();
// 商品信息集合
childs = new HashMap<String, List<MiddleBean.StoreInfo.GoodsInfo>>();
for (int i = 0; i < 5; i++) {
groups.add(new MiddleBean.StoreInfo(i + "", "100","刷新的" + (i + 1) + "个店铺"));
// 创建商品集合
List<MiddleBean.StoreInfo.GoodsInfo> goods = new ArrayList<>();
for (int j = 0; j <= i; j++) {
int[] img = {R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz};
//i-j 就是商品的id, 对应着第几个店铺的第几个商品,1-1 就是第一个店铺的第一个商品
goods.add(new MiddleBean.StoreInfo.GoodsInfo(i+"",j+"","商品"+j,"商品描述"+j,1.0,2.0,"","",R.drawable.cmaz,1));
}
childs.put(groups.get(i).getId(), goods);
}
}
/**
* 此处用于测试加载更多
*/
private void loadData() {
mcontext = this;
// 店铺信息集合
groups = new ArrayList<MiddleBean.StoreInfo>();
// 商品信息集合
childs = new HashMap<String, List<MiddleBean.StoreInfo.GoodsInfo>>();
for (int i = 0; i < 2; i++) {
groups.add(new MiddleBean.StoreInfo(i + "", "100","加载更多的" + (i + 1) + "个店铺"));
// 创建商品集合
List<MiddleBean.StoreInfo.GoodsInfo> goods = new ArrayList<>();
for (int j = 0; j <= i; j++) {
int[] img = {R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz, R.drawable.cmaz};
//i-j 就是商品的id, 对应着第几个店铺的第几个商品,1-1 就是第一个店铺的第一个商品
goods.add(new MiddleBean.StoreInfo.GoodsInfo(i+"",j+"","商品"+j,"商品描述"+j,1.0,2.0,"","",R.drawable.cmaz,1));
}
childs.put(groups.get(i).getId(), goods);
}
}
private void initData() {
mcontext = this;
String jsonStr = "{\n" +
"\t\"code\": \"0\",\n" +
"\t\"msg\": \"查看成功\",\n" +
"\t\"data\": [{\n" +
"\t\t\"merchantCode\": \"3\",\n" +
"\t\t\"isLatest\": 0,\n" +
"\t\t\"isDeleted\": 0,\n" +
"\t\t\"isEnabled\": 0,\n" +
"\t\t\"businessName\": \"北京测试1\",\n" +
"\t\t\"id\": 22,\n" +
"\t\t\"userId\": 32,\n" +
"\t\t\"productList\": [{\n" +
"\t\t\t\"cartSum\": 1,\n" +
"\t\t\t\"couponOriginalCost\": \"50\",\n" +
"\t\t\t\"couponName\": \"哇哇哇哇哇\",\n" +
"\t\t\t\"addTime\": 1536633418000,\n" +
"\t\t\t\"productImg\": \"5131.png,5132.png,5133.png\",\n" +
"\t\t\t\"currentPrice\": \"3880\",\n" +
"\t\t\t\"title\": \"海志Q1复古圆键帽有线键盘无线静音巧克力办公家用笔记本USB接口\"\n" +
"\t\t}, {\n" +
"\t\t\t\"cartSum\": 1,\n" +
"\t\t\t\"couponOriginalCost\": \"200\",\n" +
"\t\t\t\"couponName\": \"小小苏\",\n" +
"\t\t\t\"addTime\": 1536633440000,\n" +
"\t\t\t\"productImg\": \"6111.png,6112.png,6113.png\",\n" +
"\t\t\t\"currentPrice\": \"6900\",\n" +
"\t\t\t\"title\": \"灭蚊灯家用室内插电式一扫光驱蚊器防蚊灭蚊神器婴儿捕蚊子全自动\"\n" +
"\t\t}, {\n" +
"\t\t\t\"cartSum\": 1,\n" +
"\t\t\t\"addTime\": 1536633428000,\n" +
"\t\t\t\"productImg\": \"5161.png,5162.png,5163.png\",\n" +
"\t\t\t\"currentPrice\": \"23800\",\n" +
"\t\t\t\"title\": \"得力9939碎纸机办公迷你家用颗粒电动小型大功率纸张文件粉碎机\"\n" +
"\t\t}, {\n" +
"\t\t\t\"cartSum\": 1,\n" +
"\t\t\t\"addTime\": 1536633434000,\n" +
"\t\t\t\"productImg\": \"6121.png,6122.png,6123.png\",\n" +
"\t\t\t\"currentPrice\": \"8900\",\n" +
"\t\t\t\"title\": \"德国灭蚊灯室内一扫光插电式驱蚊器防蚊神器无辐射静音婴儿全自动\"\n" +
"\t\t}]\n" +
"\t}, {\n" +
"\t\t\"merchantCode\": \"4\",\n" +
"\t\t\"isLatest\": 0,\n" +
"\t\t\"isDeleted\": 0,\n" +
"\t\t\"isEnabled\": 0,\n" +
"\t\t\"businessName\": \"北京测试2\",\n" +
"\t\t\"id\": 23,\n" +
"\t\t\"userId\": 32,\n" +
"\t\t\"productList\": [{\n" +
"\t\t\t\"cartSum\": 1,\n" +
"\t\t\t\"addTime\": 1536633423000,\n" +
"\t\t\t\"productImg\": \"5141.png,5142.png,5143.png\",\n" +
"\t\t\t\"currentPrice\": \"3980\",\n" +
"\t\t\t\"title\": \"HP/惠普S1000无线鼠标静音无声男女生电脑办公笔记本台式无限游戏\"\n" +
"\t\t}]\n" +
"\t}, {\n" +
"\t\t\"merchantCode\": \"5\",\n" +
"\t\t\"isLatest\": 0,\n" +
"\t\t\"isDeleted\": 0,\n" +
"\t\t\"isEnabled\": 0,\n" +
"\t\t\"businessName\": \"北京测试3\",\n" +
"\t\t\"id\": 24,\n" +
"\t\t\"userId\": 32,\n" +
"\t\t\"productList\": [{\n" +
"\t\t\t\"cartSum\": 1,\n" +
"\t\t\t\"couponOriginalCost\": \"100\",\n" +
"\t\t\t\"couponName\": \"嘤嘤嘤\",\n" +
"\t\t\t\"addTime\": 1536633514000,\n" +
"\t\t\t\"productImg\": \"5151.png,5152.png,5153.png\",\n" +
"\t\t\t\"currentPrice\": \"79900\",\n" +
"\t\t\t\"title\": \"康亿B类点钞机新版人民币验钞机银行专用小型便携式办公家用商用\"\n" +
"\t\t}]\n" +
"\t}]\n" +
"}" ;
JsonReader jsonReader = new JsonReader(new StringReader(jsonStr));//其中jsonContext为String类型的Json数据
jsonReader.setLenient(true);
ShopCartListBean listBean = new Gson().fromJson(jsonReader , ShopCartListBean.class) ;
// 店鋪集合
List<ShopCartListBean.DataBean> storeLists = listBean.getData();
for (int i = 0; i < storeLists.size(); i++) {
// 获取所有商品集合
groups2.add(new MiddleBean.StoreInfo(storeLists.get(i).getId()+"" , storeLists.get(i).getMerchantCode() , storeLists.get(i).getBusinessName())) ;
// 创建商品集合
List<MiddleBean.StoreInfo.GoodsInfo> goodsInfos = new ArrayList<>() ;
// 根据店铺的id,获取每个店铺下边的商品集合
List<ShopCartListBean.DataBean.ProductListBean> tempProductList = storeLists.get(i).getProductList();
// 遍历每个店铺下边的商品集合
for (int j = 0; j < tempProductList.size(); j++){
goodsInfos.add(new MiddleBean.StoreInfo.GoodsInfo(storeLists.get(i).getId()+"",tempProductList.get(j).getMerchantId()+"" ,
tempProductList.get(j).getCouponName() , tempProductList.get(j).getTitle() , Double.parseDouble(tempProductList.get(j).getCurrentPrice()),
Double.parseDouble("1.0") , "1.0" , "1.0" , R.drawable.cmaz , tempProductList.get(j).getCartSum())) ;
}
childs2.put(groups2.get(i).getId() , goodsInfos) ;
}
// Log.e("TAG" , "測試中的:groups2: " + groups2.size() +", childs2: " + childs2.size()) ;
}
private void initView() {
expandableListView = (SExpandableListView) findViewById(R.id.elv_coupon);
}
}
2>:adapter代码如下:
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/10/6 10:20
* Version 1.0
* Params:
* Description: 购物车适配器
*/
public class ShopcatAdapter extends BaseExpandableListAdapter {
private List<MiddleBean.StoreInfo> groups;
//这个String对应着StoreInfo的Id,也就是店铺的Id
private Map<String, List<MiddleBean.StoreInfo.GoodsInfo>> childrens;
private Context mcontext;
private CheckInterface checkInterface;
private ModifyCountInterface modifyCountInterface;
private GroupEditorListener groupEditorListener;
private int count = 0;
private boolean flag=true; //组的编辑按钮是否可见,true可见,false不可见
private LayoutInflater inflater;
public ShopcatAdapter(List<MiddleBean.StoreInfo> groups, Map<String, List<MiddleBean.StoreInfo.GoodsInfo>> childrens, Context mcontext) {
this.groups = groups;
this.childrens = childrens;
this.mcontext = mcontext;
inflater = LayoutInflater.from(mcontext);
Log.e("TAG" , "groups:"+new Gson().toJson(groups)) ;
Log.e("TAG" , "childrens:"+new Gson().toJson(childrens)) ;
}
@Override
public int getGroupCount() {
return groups.size();
}
@Override
public int getChildrenCount(int groupPosition) {
String groupId = groups.get(groupPosition).getId();
return childrens.get(groupId).size();
}
@Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
List<MiddleBean.StoreInfo.GoodsInfo> childs = childrens.get(groups.get(groupPosition).getId());
return childs.get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
private Map<Integer,Boolean> map=new HashMap<>();// 存放已被选中的CheckBox
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
final GroupViewHolder groupViewHolder;
if (convertView == null) {
convertView =inflater.inflate(R.layout.item_shopcat_group, null);
groupViewHolder = new GroupViewHolder(convertView);
convertView.setTag(groupViewHolder);
} else {
groupViewHolder = (GroupViewHolder) convertView.getTag();
}
final MiddleBean.StoreInfo group = (MiddleBean.StoreInfo) getGroup(groupPosition);
groupViewHolder.storeName.setText(group.getName());
groupViewHolder.storeCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
group.setChoosed(((CheckBox) v).isChecked());
checkInterface.checkGroup(groupPosition, ((CheckBox) v).isChecked());
}
});
groupViewHolder.storeCheckBox.setChecked(group.isChoosed());
/*groupViewHolder.storeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked==true){
map.put(groupPosition,true);
group.setChoosed(((CheckBox) buttonView).isChecked());
checkInterface.checkGroup(groupPosition, ((CheckBox) buttonView).isChecked());
}else {
map.remove(groupPosition);
group.setChoosed(((CheckBox) buttonView).isChecked());
checkInterface.checkGroup(groupPosition, ((CheckBox) buttonView).isChecked());
}
}
});
if(map!=null&&map.containsKey(groupPosition)){
groupViewHolder.storeCheckBox.setChecked(true);
}else {
groupViewHolder.storeCheckBox.setChecked(false);
}*/
/**【文字指的是组的按钮的文字】
* 当我们按下ActionBar的 "编辑"按钮, 应该把所有组的文字显示"编辑",并且设置按钮为不可见
* 当我们完成编辑后,再把组的编辑按钮设置为可见
* 不懂,请自己操作淘宝,观察一遍
*/
/*if(group.isActionBarEditor()){
group.setEditor(false);
groupViewHolder.storeEdit.setVisibility(View.GONE);
flag=false;
}else{
flag=true;
groupViewHolder.storeEdit.setVisibility(View.VISIBLE);
}*/
/**
* 思路:当我们按下组的"编辑"按钮后,组处于编辑状态,文字显示"完成"
* 当我们点击“完成”按钮后,文字显示"编辑“,组处于未编辑状态
*/
if (group.isEditor()) {
groupViewHolder.storeEdit.setText("完成");
} else {
groupViewHolder.storeEdit.setText("编辑");
}
groupViewHolder.storeEdit.setOnClickListener(new GroupViewClick(group, groupPosition, groupViewHolder.storeEdit));
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final ChildViewHolder childViewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_shopcat_product, null);
childViewHolder = new ChildViewHolder(convertView);
convertView.setTag(childViewHolder);
} else {
childViewHolder = (ChildViewHolder) convertView.getTag();
}
/**
* 根据组的编辑按钮的可见与不可见,去判断是组对下辖的子元素编辑 还是ActionBar对组的下瞎元素的编辑
* 如果组的编辑按钮可见,那么肯定是组对自己下辖元素的编辑
* 如果组的编辑按钮不可见,那么肯定是ActionBar对组下辖元素的编辑
*/
/*if(flag){
if (groups.get(groupPosition).isEditor()) {
childViewHolder.editGoodsData.setVisibility(View.VISIBLE);
childViewHolder.delGoods.setVisibility(View.VISIBLE);
childViewHolder.goodsData.setVisibility(View.GONE);
} else {
childViewHolder.delGoods.setVisibility(View.VISIBLE);
childViewHolder.goodsData.setVisibility(View.VISIBLE);
childViewHolder.editGoodsData.setVisibility(View.GONE);
}
}else{
if(groups.get(groupPosition).isActionBarEditor()){
childViewHolder.delGoods.setVisibility(View.GONE);
childViewHolder.editGoodsData.setVisibility(View.VISIBLE);
childViewHolder.goodsData.setVisibility(View.GONE);
}else{
childViewHolder.delGoods.setVisibility(View.VISIBLE);
childViewHolder.goodsData.setVisibility(View.VISIBLE);
childViewHolder.editGoodsData.setVisibility(View.GONE);
}
}*/
final MiddleBean.StoreInfo.GoodsInfo child = (MiddleBean.StoreInfo.GoodsInfo) getChild(groupPosition, childPosition);
if (child != null) {
childViewHolder.goodsName.setText(child.getDesc());
childViewHolder.goodsPrice.setText("¥" + child.getPrice() + "");
// 加号与减号中间的数字
childViewHolder.goodsNum.setText(String.valueOf(child.getCount()));
childViewHolder.goodsImage.setImageResource(R.mipmap.ic_launcher);
childViewHolder.goods_size.setText("门票:" + child.getColor() + ",类型:" + child.getSize());
//设置打折前的原价
SpannableString spannableString = new SpannableString("¥" + child.getPrime_price() + "");
StrikethroughSpan span = new StrikethroughSpan();
spannableString.setSpan(span,0,spannableString.length()-1+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
//避免无限次的append
if (childViewHolder.goodsPrimePrice.length() > 0) {
childViewHolder.goodsPrimePrice.setText("");
}
childViewHolder.goodsPrimePrice.setText(spannableString);
childViewHolder.goodsBuyNum.setText("x" + child.getCount() + "");
childViewHolder.singleCheckBox.setChecked(child.isChoosed());
childViewHolder.singleCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
child.setChoosed(((CheckBox) v).isChecked());
childViewHolder.singleCheckBox.setChecked(((CheckBox) v).isChecked());
checkInterface.checkChild(groupPosition, childPosition, ((CheckBox) v).isChecked());
}
});
/**
* 点击加号
*/
childViewHolder.increaseGoodsNum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
modifyCountInterface.doIncrease(groupPosition, childPosition, childViewHolder.goodsNum, childViewHolder.singleCheckBox.isChecked());
}
});
/**
* 点击减号
*/
childViewHolder.reduceGoodsNum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
modifyCountInterface.doDecrease(groupPosition, childPosition, childViewHolder.goodsNum, childViewHolder.singleCheckBox.isChecked());
}
});
childViewHolder.goodsNum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(groupPosition,childPosition,childViewHolder.goodsNum,childViewHolder.singleCheckBox.isChecked(),child);
}
});
childViewHolder.delGoods.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(mcontext)
.setMessage("确定要删除该商品吗")
.setNegativeButton("取消",null)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
modifyCountInterface.childDelete(groupPosition,childPosition);
}
})
.create()
.show();
}
});
}
return convertView;
}
/**
*
* @param groupPosition
* @param childPosition
* @param showCountView
* @param isChecked
* @param child
*/
private void showDialog(final int groupPosition, final int childPosition, final View showCountView,final boolean isChecked, final MiddleBean.StoreInfo.GoodsInfo child) {
final AlertDialog.Builder alertDialog_Builder=new AlertDialog.Builder(mcontext);
View view= LayoutInflater.from(mcontext).inflate(R.layout.dialog_change_num,null);
final AlertDialog dialog=alertDialog_Builder.create();
dialog.setView(view);//errored,这里是dialog,不是alertDialog_Buidler
count=child.getCount();
final EditText num= (EditText) view.findViewById(R.id.dialog_num);
num.setText(count+"");
//自动弹出键盘
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
UtilTool.showKeyboard(mcontext,showCountView);
}
});
final TextView increase= (TextView) view.findViewById(R.id.dialog_increaseNum);
final TextView DeIncrease=(TextView)view.findViewById(R.id.dialog_reduceNum);
final TextView pButton= (TextView) view.findViewById(R.id.dialog_Pbutton);
final TextView nButton= (TextView) view.findViewById(R.id.dialog_Nbutton);
nButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
pButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int number=Integer.parseInt(num.getText().toString().trim());
if(number==0){
dialog.dismiss();
}else{
UtilsLog.i("数量="+number+"");
num.setText(String.valueOf(number));
child.setCount(number);
modifyCountInterface.doUpdate(groupPosition,childPosition,showCountView,isChecked);
dialog.dismiss();
}
}
});
increase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
count++;
num.setText(String.valueOf(count));
}
});
DeIncrease.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(count>1){
count--;
num.setText(String.valueOf(count));
}
}
});
dialog.show();
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
public GroupEditorListener getGroupEditorListener() {
return groupEditorListener;
}
public void setGroupEditorListener(GroupEditorListener groupEditorListener) {
this.groupEditorListener = groupEditorListener;
}
public CheckInterface getCheckInterface() {
return checkInterface;
}
public void setCheckInterface(CheckInterface checkInterface) {
this.checkInterface = checkInterface;
}
public ModifyCountInterface getModifyCountInterface() {
return modifyCountInterface;
}
public void setModifyCountInterface(ModifyCountInterface modifyCountInterface) {
this.modifyCountInterface = modifyCountInterface;
}
static class GroupViewHolder {
@BindView(R.id.store_checkBox)
CheckBox storeCheckBox;
@BindView(R.id.store_name)
TextView storeName;
@BindView(R.id.store_edit)
TextView storeEdit;
public GroupViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
/**
* 店铺的复选框
*/
public interface CheckInterface {
/**
* 组选框状态改变触发的事件
*
* @param groupPosition 组元素的位置
* @param isChecked 组元素的选中与否
*/
void checkGroup(int groupPosition, boolean isChecked);
/**
* 子选框状态改变触发的事件
*
* @param groupPosition 组元素的位置
* @param childPosition 子元素的位置
* @param isChecked 子元素的选中与否
*/
void checkChild(int groupPosition, int childPosition, boolean isChecked);
}
/**
* 改变数量的接口
*/
public interface ModifyCountInterface {
/**
* 增加操作
*
* @param groupPosition 组元素的位置
* @param childPosition 子元素的位置
* @param showCountView 用于展示变化后数量的View
* @param isChecked 子元素选中与否
*/
void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);
void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);
void doUpdate(int groupPosition, int childPosition, View showCountView, boolean isChecked);
/**
* 删除子Item
*
* @param groupPosition
* @param childPosition
*/
void childDelete(int groupPosition, int childPosition);
}
/**
* 监听编辑状态
*/
public interface GroupEditorListener {
void groupEditor(int groupPosition);
}
/**
* 使某个小组处于编辑状态
*/
private class GroupViewClick implements View.OnClickListener {
private MiddleBean.StoreInfo group;
private int groupPosition;
private TextView editor;
public GroupViewClick(MiddleBean.StoreInfo group, int groupPosition, TextView editor) {
this.group = group;
this.groupPosition = groupPosition;
this.editor = editor;
}
@Override
public void onClick(View v) {
if (editor.getId() == v.getId()) {
groupEditorListener.groupEditor(groupPosition);
if (group.isEditor()) {
group.setEditor(false);
} else {
group.setEditor(true);
}
notifyDataSetChanged();
}
}
}
static class ChildViewHolder {
@BindView(R.id.single_checkBox)
CheckBox singleCheckBox;
@BindView(R.id.goods_image)
ImageView goodsImage;
@BindView(R.id.goods_name)
TextView goodsName;
@BindView(R.id.goods_size)
TextView goods_size;
@BindView(R.id.goods_price)
TextView goodsPrice;
@BindView(R.id.goods_prime_price)
TextView goodsPrimePrice;
@BindView(R.id.goods_buyNum)
TextView goodsBuyNum;
@BindView(R.id.goods_data)
RelativeLayout goodsData;
@BindView(R.id.reduce_goodsNum)
TextView reduceGoodsNum;
@BindView(R.id.goods_Num)
TextView goodsNum;
// 加号
@BindView(R.id.increase_goods_Num)
TextView increaseGoodsNum;
@BindView(R.id.goodsSize)
TextView goodsSize;
@BindView(R.id.del_goods)
TextView delGoods;
@BindView(R.id.edit_goods_data)
LinearLayout editGoodsData;
public ChildViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}