布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.desktop.gouwuche_demo.view.activity.ShoppingActivity"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.desktop.gouwuche_demo.view.costom.MyExpanableListView android:id="@+id/expandable_view" android:layout_width="match_parent" android:layout_height="wrap_content"> </com.example.desktop.gouwuche_demo.view.costom.MyExpanableListView> </LinearLayout> </ScrollView> <RelativeLayout android:id="@+id/relative_progress" android:layout_width="match_parent" android:layout_above="@+id/line_jie" android:visibility="gone" android:layout_height="match_parent"> <ProgressBar android:layout_width="wrap_content" android:layout_centerInParent="true" android:layout_height="wrap_content" /> </RelativeLayout> <LinearLayout android:id="@+id/line_jie" android:visibility="gone" android:layout_width="match_parent" android:layout_height="50dp" android:background="#fff" android:layout_alignParentBottom="true" android:orientation="horizontal" > <CheckBox android:id="@+id/checkAll" android:button="@null" android:layout_width="25dp" android:background="@drawable/check_box_sel" android:layout_height="25dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全选" /> <TextView android:id="@+id/text_heji" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:textSize="18dp" android:layout_weight="2" android:text="合计:¥0.00" /> <Button android:id="@+id/text_jiesuan" android:layout_width="0dp" android:background="#ff00" android:layout_weight="1" android:layout_height="match_parent" android:text="去结算(0)"/> </LinearLayout> </RelativeLayout>
一级布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal" > <CheckBox android:id="@+id/check_group" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/check_box_sel" android:button="@null"/> <TextView android:id="@+id/txt_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="aaaaa"/> </LinearLayout>
二级布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" > <RelativeLayout android:id="@+id/rel" android:layout_toLeftOf="@+id/del" android:layout_width="match_parent" android:layout_height="match_parent"> <CheckBox android:id="@+id/check_child" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/check_box_sel" android:layout_centerVertical="true" android:button="@null"/> <ImageView android:id="@+id/child_img" android:layout_width="80dp" android:layout_marginLeft="10dp" android:layout_centerVertical="true" android:layout_toRightOf="@id/check_child" android:layout_height="80dp" /> <TextView android:id="@+id/child_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/child_img" android:layout_alignTop="@id/child_img" android:maxLines="2" android:minLines="2" android:text="aaaa"/> <TextView android:id="@+id/price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/child_img" android:layout_alignBottom="@id/child_img" android:textColor="#ff00" android:text="aaa"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignBottom="@id/child_img" android:orientation="horizontal"> <TextView android:id="@+id/child_jian" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/jian_line" android:padding="5dp" android:text="一"/> <TextView android:id="@+id/child_num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:background="@drawable/jian_line" android:text="1"/> <TextView android:id="@+id/child_jia" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/jian_line" android:padding="5dp" android:text="十"/> </LinearLayout> </RelativeLayout> <TextView android:id="@+id/del" android:layout_width="50dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_alignBottom="@id/rel" android:layout_alignTop="@id/rel" android:layout_marginLeft="3dp" android:gravity="center" android:background="#ff00" android:text="删除"/> </RelativeLayout>
MainActivity代码:
public class ShoppingActivity extends AppCompatActivity implements Shopping_view_face, View.OnClickListener { private ExpandableListView expandableListView; private CheckBox checkAll; private TextView textheji; private TextView text_jiesuan; private ShopPresenter shopPresenter; private int uid=2815; private RelativeLayout relative_progress; private ShoppingBean shoppingBean; private LinearLayout linear_jie; private ShopAdapter shopAdapter; private CountAndPrice countAndPrice; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop); expandableListView = (ExpandableListView) findViewById(R.id.expandable_view); checkAll = (CheckBox) findViewById(R.id.checkAll); textheji = (TextView) findViewById(R.id.text_heji); text_jiesuan = (TextView) findViewById(R.id.text_jiesuan); relative_progress = (RelativeLayout) findViewById(R.id.relative_progress); linear_jie = (LinearLayout) findViewById(R.id.line_jie); //去掉默认的图标 expandableListView.setGroupIndicator(null); shopPresenter = new ShopPresenter(this); checkAll.setOnClickListener(this); text_jiesuan.setOnClickListener(this); } Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what==0){ countAndPrice = (CountAndPrice) msg.obj; text_jiesuan.setText("去结算:("+ countAndPrice.getCount()+")"); textheji.setText("合计:¥"+ countAndPrice.getPrice()); } } }; @Override protected void onResume() { super.onResume(); //进度条显示 relative_progress.setVisibility(View.VISIBLE); //请求数据 shopPresenter.setData(uid, ApiUrl.shop_url); } @Override public void setVSuccess(final ShoppingBean shoppingBean) { this.shoppingBean=shoppingBean; runOnUiThread(new Runnable() { @Override public void run() { relative_progress.setVisibility(View.GONE); //请求数据成功后 if ("0".equals(shoppingBean.getCode())){ //结算按钮显示 linear_jie.setVisibility(View.VISIBLE); //根据子条目是否选中 决定该组是否选中 初始化isChildchecked数据 for (int i=0;i<shoppingBean.getData().size();i++){ if (isAllChildInGroupSelected(i)){ shoppingBean.getData().get(i).setGroupChecked(true); } } //点击全选的复选框 实现全选 checkAll.setChecked(isAllGroupChecked()); //设置适配器 shopAdapter = new ShopAdapter(shoppingBean,ShoppingActivity.this,relative_progress,shopPresenter,handler); expandableListView.setAdapter(shopAdapter); //二级列表全部展开 for (int i=0;i<shoppingBean.getData().size();i++){ expandableListView.expandGroup(i); } //根据子条目是否选中 设置价格和数量 shopAdapter.sendPriceAndCount(); }else { //如果没有数据结算按钮隐藏 linear_jie.setVisibility(View.GONE); } } }); } private boolean isAllGroupChecked() { for (int i=0;i<shoppingBean.getData().size();i++){ //一级列表是否选中 if (!shoppingBean.getData().get(i).isGroupChecked()){ return false; } } return true; } private boolean isAllChildInGroupSelected(int groupPosition) { for (int i=0;i<shoppingBean.getData().get(groupPosition).getList().size();i++){ if (shoppingBean.getData().get(groupPosition).getList().get(i).getSelected()==0){ return false; } } return true; } @Override public void setVError(String s) { } @Override public void onClick(View view) { switch (view.getId()){ case R.id.checkAll: shopAdapter.setAllChildState(checkAll.isChecked()); break; case R.id.text_jiesuan: Intent intent=new Intent(ShoppingActivity.this,ConfirmActivity.class); intent.putExtra("uid",uid); intent.putExtra("price",countAndPrice); startActivity(intent); break; } } }
isAllGroupChecked()
需要在bean中设置
public static class DataBean { public boolean isGroupChecked(){ return isGroupChecked; } public void setGroupChecked(boolean groupChecked) { isGroupChecked = groupChecked; } private boolean isGroupChecked; private String sellerName; private String sellerid;
适配器:
public class ShopAdapter extends BaseExpandableListAdapter{ private Handler handler; private ShopPresenter shopPresenter; private RelativeLayout relative_progress; ShoppingBean shoppingBean; Context con; private int childI; private int size; private int uid=2815; private int index; private int allsize; public ShopAdapter(ShoppingBean shoppingBean, Context con, RelativeLayout relative_progress, ShopPresenter shopPresenter, Handler handler) { this.shoppingBean = shoppingBean; this.con = con; this.relative_progress=relative_progress; this.shopPresenter=shopPresenter; this.handler=handler; } @Override public int getGroupCount() { return shoppingBean.getData().size(); } @Override public int getChildrenCount(int i) { return shoppingBean.getData().get(i).getList().size(); } @Override public Object getGroup(int i) { return shoppingBean.getData().get(i); } @Override public Object getChild(int i, int i1) { return shoppingBean.getData().get(i).getList().get(i1); } @Override public long getGroupId(int i) { return i; } @Override public long getChildId(int i, int i1) { return i1; } @Override public boolean hasStableIds() { return true; } @Override public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) { final GroupHolder gh; if (view==null){ view = View.inflate(con, R.layout.group_item, null); gh=new GroupHolder(); gh.check_group=(CheckBox) view.findViewById(R.id.check_group); gh.text_group=(TextView) view.findViewById(R.id.txt_group); view.setTag(gh); }else { gh= (GroupHolder) view.getTag(); } final ShoppingBean.DataBean dataBean = shoppingBean.getData().get(i); gh.text_group.setText(dataBean.getSellerName()); gh.check_group.setChecked(dataBean.isGroupChecked()); //点击一级的复选框 gh.check_group.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { relative_progress.setVisibility(View.VISIBLE); size = dataBean.getList().size(); childI = 0; //改变状态 updataAllInGroup(gh.check_group.isChecked(),dataBean); } }); return view; } /* * 请求修改的接口实现一级中的状态改变 * */ private void updataAllInGroup(final boolean checked, final ShoppingBean.DataBean dataBean) { ShoppingBean.DataBean.ListBean listBean = dataBean.getList().get(childI); //?uid=71&sellerid=1&pid=1&selected=0&num=10 Map<String, String> map=new HashMap<>(); map.put("uid", String.valueOf(uid)); map.put("sellerid", String.valueOf(listBean.getSellerid())); map.put("pid", String.valueOf(listBean.getPid())); map.put("selected", String.valueOf(checked ? 1:0)); map.put("num", String.valueOf(listBean.getNum())); OkHttp3Util.doPost(ApiUrl.update_url, map, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ childI=childI+1; if (childI<size){ updataAllInGroup(checked,dataBean); }else { shopPresenter.setData(uid,ApiUrl.shop_url); } } } }); } @Override public View getChildView(final int i, int i1, boolean b, View view, ViewGroup viewGroup) { ChildHolder ch; if (view==null){ view=View.inflate(con,R.layout.child_item,null); ch=new ChildHolder(); ch.check_child=(CheckBox) view.findViewById(R.id.check_child); ch.image_child=(ImageView) view.findViewById(R.id.child_img); ch.text_del=(TextView) view.findViewById(R.id.del); ch.text_jia=(TextView) view.findViewById(R.id.child_jia); ch.text_jian=(TextView) view.findViewById(R.id.child_jian); ch.text_num=(TextView) view.findViewById(R.id.child_num); ch.text_title=(TextView) view.findViewById(R.id.child_title); ch.text_price=(TextView) view.findViewById(R.id.price); view.setTag(ch); }else { ch= (ChildHolder) view.getTag(); } final ShoppingBean.DataBean.ListBean listBean = shoppingBean.getData().get(i).getList().get(i1); ch.text_price.setText("¥"+listBean.getBargainPrice()); ch.text_title.setText(listBean.getTitle()); ch.text_num.setText(listBean.getNum()+""); ch.check_child.setChecked(listBean.getSelected()==0? false:true); Glide.with(con).load(listBean.getImages().split("\\|")[0]).into(ch.image_child); //复选框 ch.check_child.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { updateChildChecked(listBean); } }); //加号 ch.text_jia.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { updateChildNum(listBean,true); } }); //减号 ch.text_jian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //商品数量为1的时候直接返回 if (listBean.getNum()==1){ return; } updateChildNum(listBean,false); } }); //删除 //https://www.zhaoapi.cn/product/deleteCart?uid=72&pid=1 ch.text_del.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { deleteChild(listBean); } }); return view; } private void deleteChild(ShoppingBean.DataBean.ListBean listBean) { int pid = listBean.getPid(); Map<String, String> map=new HashMap<String, String>(); map.put("uid", String.valueOf(uid)); map.put("pid", String.valueOf(pid)); OkHttp3Util.doPost(ApiUrl.del_url, map, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ String string = response.body().string(); final DeleteBean deleteBean = new Gson().fromJson(string, DeleteBean.class); CommonUtils.runOnUIThread(new Runnable() { @Override public void run() { if ("0".equals(deleteBean.getCode())){ Toast.makeText(con,deleteBean.getMsg(),Toast.LENGTH_SHORT).show(); shopPresenter.setData(uid,ApiUrl.shop_url); }else { Toast.makeText(con,deleteBean.getMsg(),Toast.LENGTH_SHORT).show(); } } }); } } }); } /* * 点击加号或减号改变接口中商品的数量 * */ private void updateChildNum(ShoppingBean.DataBean.ListBean listBean, boolean b) { relative_progress.setVisibility(View.VISIBLE); //?uid=71&sellerid=1&pid=1&selected=0&num=10 Map<String, String> map=new HashMap<>(); map.put("uid", String.valueOf(uid)); map.put("sellerid", String.valueOf(listBean.getSellerid())); map.put("pid", String.valueOf(listBean.getPid())); map.put("selected", String.valueOf(listBean.getSelected())); if (b){ map.put("num", String.valueOf(listBean.getNum()+1)); }else { map.put("num", String.valueOf(listBean.getNum()-1)); } OkHttp3Util.doPost(ApiUrl.update_url, map, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ //刷新数据 shopPresenter.setData(uid,ApiUrl.shop_url); } } }); } /* 改变二级复选框的状态 */ private void updateChildChecked(ShoppingBean.DataBean.ListBean listBean) { relative_progress.setVisibility(View.VISIBLE); //?uid=71&sellerid=1&pid=1&selected=0&num=10 Map<String, String> map=new HashMap<>(); map.put("uid", String.valueOf(uid)); map.put("sellerid", String.valueOf(listBean.getSellerid())); map.put("pid", String.valueOf(listBean.getPid())); map.put("selected", String.valueOf(listBean.getSelected()==0 ? 1:0)); map.put("num", String.valueOf(listBean.getNum())); OkHttp3Util.doPost(ApiUrl.update_url, map, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ shopPresenter.setData(uid,ApiUrl.shop_url); } } }); } @Override public boolean isChildSelectable(int i, int i1) { return true; } //计算价格和数量 public void sendPriceAndCount() { double price=0; int count=0; for (int i=0;i<shoppingBean.getData().size();i++){ for (int j=0;j<shoppingBean.getData().get(i).getList().size();j++){ if (shoppingBean.getData().get(i).getList().get(j).getSelected()==1){ price+=shoppingBean.getData().get(i).getList().get(j).getBargainPrice()*shoppingBean.getData().get(i).getList().get(j).getNum(); count+=shoppingBean.getData().get(i).getList().get(j).getNum(); } } //格式化 保留两位小数 DecimalFormat decimalFormat=new DecimalFormat("#.00"); String format = decimalFormat.format(price); CountAndPrice countAndPrice=new CountAndPrice(count,format); Message msg = Message.obtain(); msg.what=0; msg.obj=countAndPrice; handler.sendMessage(msg); } } //全选 根据二级的状态来实现全选 public void setAllChildState(boolean checked) { //定义一个新的集合 List<ShoppingBean.DataBean.ListBean> alllist=new ArrayList<>(); for (int i=0;i<shoppingBean.getData().size();i++){ for (int j=0;j<shoppingBean.getData().get(i).getList().size();j++){ alllist.add(shoppingBean.getData().get(i).getList().get(j)); } } relative_progress.setVisibility(View.VISIBLE); allsize = alllist.size(); index=0; updateAllChild(alllist,checked); } //改变所有的二级复选框的状态 private void updateAllChild(final List<ShoppingBean.DataBean.ListBean> alllist, final boolean checked) { ShoppingBean.DataBean.ListBean listBean = alllist.get(index); //?uid=71&sellerid=1&pid=1&selected=0&num=10 Map<String, String> map=new HashMap<>(); map.put("uid", String.valueOf(uid)); map.put("sellerid", String.valueOf(listBean.getSellerid())); map.put("pid", String.valueOf(listBean.getPid())); map.put("selected", String.valueOf(checked ? 1:0)); map.put("num", String.valueOf(listBean.getNum())); OkHttp3Util.doPost(ApiUrl.update_url, map, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ index=index+1; if (index<allsize){ updateAllChild(alllist,checked); }else { shopPresenter.setData(uid,ApiUrl.shop_url); } } } }); } class GroupHolder{ CheckBox check_group; TextView text_group; } class ChildHolder{ CheckBox check_child; ImageView image_child; TextView text_title; TextView text_price; TextView text_jian; TextView text_num; TextView text_jia; TextView text_del; } }
一些小的布局文件以及样式
textView的边框样式
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:color="#000" android:width="1dp"/> </shape>
复选框中的样式
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:drawable="@drawable/shopping_cart_checked"/> <item android:state_checked="false" android:drawable="@drawable/shopping_cart_none_check"/> <item android:drawable="@drawable/shopping_cart_none_check"/> </selector>
二级列表放在scrollView里面要重新计算二级列表的高度
自定义二级列表,
public class MyExpanableListView extends ExpandableListView{ public MyExpanableListView(Context context) { super(context); } public MyExpanableListView(Context context, AttributeSet attrs) { super(context, attrs); } public MyExpanableListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, height); } }