佈局文件
Main 佈局
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="@+id/Rl"
>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Quan_Box"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Jia_Text"
android:text="價格"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Zong_Text"
android:text="去結算"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/Expand_View"
android:layout_above="@+id/Rl"
></ExpandableListView>
</RelativeLayout>
Group佈局
<?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="match_parent"
android:orientation="horizontal"
>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Group_Box"
android:focusable="false"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Group_Text"
/>
</LinearLayout>
child佈局
<?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="120dp"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Child_Box"
android:focusable="false"
/>
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/Child_Image"
android:layout_marginLeft="20dp"
android:src="@mipmap/ic_launcher"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Child_Title"
android:maxLines="2"
android:text="商品標題"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Child_Price"
android:text="¥0.0"
android:layout_marginTop="10dp"
/>
</LinearLayout>
<com.example.gouwuche.ziview.JiaJianView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Jia_Jian_View"
></com.example.gouwuche.ziview.JiaJianView>
</LinearLayout>
加減佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:background="#99000000"
android:gravity="center_vertical"
android:padding="2dp">
<TextView
android:id="@+id/delete_tv"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="center"
android:text="-"
android:textSize="16sp" />
<TextView
android:id="@+id/product_number_tv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:background="#ffffff"
android:gravity="center"
android:text="1" />
<TextView
android:id="@+id/add_tv"
android:layout_width="10dp"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:background="#ffffff"
android:gravity="center"
android:text="+"
android:textSize="16sp" />
</LinearLayout>
加減
package com.example.gouwuche.ziview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.gouwuche.R;
public class JiaJianView extends LinearLayout implements View.OnClickListener {
private TextView mAdd;
private TextView mDelete;
private TextView mNumber;
//商品數量
private int mCount;
public JiaJianView(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.jiajian_item, this);
initViews();
}
private void initViews() {
mAdd = findViewById(R.id.add_tv);
mDelete = findViewById(R.id.delete_tv);
mNumber = findViewById(R.id.product_number_tv);
mAdd.setOnClickListener(this);
mDelete.setOnClickListener(this);
}
//先給初始值賦值
public void setNumber(int number){
this.mCount=number;
mNumber.setText(number+"");
}
public interface OnCountChange{
void setCount(int count);
}
private OnCountChange mOnCountChange;
public void setOnChange(OnCountChange onCountChange){
this.mOnCountChange=onCountChange;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.delete_tv:
if (mCount > 0) {
mCount--;
mNumber.setText(mCount + "");
if (mOnCountChange!=null){
mOnCountChange.setCount(mCount);
}
}else {
Toast.makeText(getContext(), "商品已售空", Toast.LENGTH_SHORT).show();
}
break;
case R.id.add_tv:
mCount++;
mNumber.setText(mCount + "");
if (mOnCountChange!=null){
mOnCountChange.setCount(mCount);
}
break;
}
}
}
購物MainActivity
package com.example.gouwuche;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.gouwuche.adapter.MyAdapter;
import com.example.gouwuche.bean.MyData;
import com.example.gouwuche.utils.OkHttpUtils;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.ArrayList;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private CheckBox Quan_Box;
private TextView Jia_Text;
private TextView Zong_Text;
private RelativeLayout Rl;
private ExpandableListView Expand_View;
private String mUrl="http://www.wanandroid.com/tools/mockapi/6523/restaurant-list";
private ArrayList<MyData.DataBean> mList=new ArrayList<>();
private MyAdapter myAdapter;
// @SuppressLint("HandlerLeak")
// private Handler mHandler=new Handler(){
// @Override
// public void handleMessage(Message msg) {
// String jsonStr= (String) msg.obj;
// Gson gson=new Gson();
// MyData myData= gson.fromJson(jsonStr,MyData.class);
// mList.addAll(myData.getData());
// myAdapter.notifyDataSetChanged();
//
// }
// };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
myAdapter = new MyAdapter(mList,this);
Expand_View.setAdapter(myAdapter);
// getNetData();
new MyTask().execute(mUrl);
myAdapter.setCallback(new MyAdapter.AdapterCallback() {
@Override
public void setGroupCheck(int groupPosition) {
boolean childAllCheck = myAdapter.isChildAllCheck(groupPosition);
myAdapter.childAllCheck(groupPosition,!childAllCheck);
myAdapter.notifyDataSetChanged();
flushBottomLayout();
}
@Override
public void setChildCheck(int groupPosition, int childPosition) {
boolean childChecked = myAdapter.isChildChecked(groupPosition, childPosition);
myAdapter.setChildChecked(groupPosition,childPosition,!childChecked);
myAdapter.notifyDataSetChanged();
flushBottomLayout();
}
@Override
public void setNumber(int groupPosition, int childPosition, int number) {
myAdapter.setShangPingNumber(groupPosition,childPosition,number);
myAdapter.notifyDataSetChanged();
flushBottomLayout();
}
});
Quan_Box.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean allGoods = myAdapter.isAllGoods();
myAdapter.setAllGoodsIsChecked(!allGoods);
myAdapter.notifyDataSetChanged();
flushBottomLayout();
}
});
}
private void initView() {
Quan_Box = (CheckBox) findViewById(R.id.Quan_Box);
Jia_Text = (TextView) findViewById(R.id.Jia_Text);
Zong_Text = (TextView) findViewById(R.id.Zong_Text);
Rl = (RelativeLayout) findViewById(R.id.Rl);
Expand_View = (ExpandableListView) findViewById(R.id.Expand_View);
//去掉自帶的小箭頭
Expand_View.setGroupIndicator(null);
}
//刷新底部視圖
private void flushBottomLayout(){
boolean allGoods = myAdapter.isAllGoods();
Quan_Box.setChecked(allGoods);
int allGoodsNumber = myAdapter.getAllGoodsNumber();
float allGoodsPrice = myAdapter.getAllGoodsPrice();
Jia_Text.setText("價格:"+allGoodsPrice);
Zong_Text.setText("去結算:"+"("+allGoodsNumber+")");
}
// private void getNetData(){
//
//
// OkHttpClient okHttpClient=new OkHttpClient();
// Request request=new Request.Builder().url(mUrl).build();
// okHttpClient.newCall(request).enqueue(new Callback() {
// @Override
// public void onFailure(Call call, IOException e) {
//
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
//
// mHandler.sendMessage(mHandler.obtainMessage(0,response.body().string()));
// }
// });
//
//
//
// }
class MyTask extends AsyncTask<String,Void,MyData>{
@Override
protected MyData doInBackground(String... strings) {
try {
String jsonStr = OkHttpUtils.getInstance().get(strings[0]);
Gson gson=new Gson();
MyData myData = gson.fromJson(jsonStr, MyData.class);
return myData;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(MyData myData) {
super.onPostExecute(myData);
mList.addAll(myData.getData());
myAdapter.notifyDataSetChanged();
}
}
}
工具類
package com.example.gouwuche.utils;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class OkHttpUtils {
private OkHttpClient okHttpClient;
private OkHttpUtils(){
okHttpClient=new OkHttpClient();
}
public static OkHttpUtils getInstance(){
return okHttpHolder.utils;
}
static class okHttpHolder{
public static final OkHttpUtils utils=new OkHttpUtils();
}
public String get(String url) throws IOException {
Request request=new Request.Builder().url(url).build();
Response execute = okHttpClient.newCall(request).execute();
return execute.body().string();
}
}
適配器
package com.example.gouwuche.adapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.example.gouwuche.R;
import com.example.gouwuche.bean.MyData;
import com.example.gouwuche.ziview.JiaJianView;
import java.util.ArrayList;
import java.util.List;
public class MyAdapter extends BaseExpandableListAdapter {
private ArrayList<MyData.DataBean> mList;
private Context mContext;
public MyAdapter(ArrayList<MyData.DataBean> mList, Context mContext) {
this.mList = mList;
this.mContext = mContext;
}
@Override
public int getGroupCount() {
return mList.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return mList.get(groupPosition).getSpus().size();
}
@Override
public Object getGroup(int groupPosition) {
return null;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder groupHolder;
if (convertView == null) {
groupHolder = new GroupHolder();
convertView = View.inflate(mContext, R.layout.group_item, null);
groupHolder.Group_Box = convertView.findViewById(R.id.Group_Box);
groupHolder.Group_Text = convertView.findViewById(R.id.Group_Text);
//這裏傳入的必須是childHolder
convertView.setTag(groupHolder);
} else {
groupHolder = (GroupHolder) convertView.getTag();
}
MyData.DataBean dataBean = mList.get(groupPosition);
groupHolder.Group_Text.setText(dataBean.getName() + "");
boolean childAllCheck = isChildAllCheck(groupPosition);
groupHolder.Group_Box.setChecked(childAllCheck);
groupHolder.Group_Box.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapterCallback != null) {
adapterCallback.setGroupCheck(groupPosition);
}
}
});
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder childHolder;
if (convertView == null) {
childHolder = new ChildHolder();
convertView = View.inflate(mContext, R.layout.child_item, null);
childHolder.Child_Box = convertView.findViewById(R.id.Child_Box);
childHolder.Child_Image = convertView.findViewById(R.id.Child_Image);
childHolder.Child_Title = convertView.findViewById(R.id.Child_Title);
childHolder.Child_Price = convertView.findViewById(R.id.Child_Price);
childHolder.Jia_Jian_View = convertView.findViewById(R.id.Jia_Jian_View);
convertView.setTag(childHolder);
} else {
childHolder = (ChildHolder) convertView.getTag();
}
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
childHolder.Child_Title.setText(spusBean.getName() + "");
childHolder.Child_Price.setText(spusBean.getSkus().get(0).getPrice() + "");
Glide.with(mContext).load(spusBean.getPic_url()).into(childHolder.Child_Image);
childHolder.Child_Box.setChecked(spusBean.isChildChecked());
childHolder.Jia_Jian_View.setNumber(spusBean.getPraise_num());
childHolder.Child_Box.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapterCallback != null) {
adapterCallback.setChildCheck(groupPosition, childPosition);
}
}
});
childHolder.Jia_Jian_View.setOnChange(new JiaJianView.OnCountChange() {
@Override
public void setCount(int count) {
if (adapterCallback != null) {
adapterCallback.setNumber(groupPosition, childPosition, count);
}
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
class GroupHolder {
private CheckBox Group_Box;
private TextView Group_Text;
}
class ChildHolder {
private CheckBox Child_Box;
private ImageView Child_Image;
private TextView Child_Title;
private TextView Child_Price;
private JiaJianView Jia_Jian_View;
}
//點擊group的CheckBox全部選中
public void childAllCheck(int groupPosition, boolean isCheck) {
MyData.DataBean dataBean = mList.get(groupPosition);
List<MyData.DataBean.SpusBean> spus = dataBean.getSpus();
for (int i = 0; i < spus.size(); i++) {
MyData.DataBean.SpusBean bean = spus.get(i);
bean.setChildChecked(isCheck);
}
}
//判斷小組是否選中
public boolean isChildAllCheck(int groupPosition) {
boolean boo = true;
MyData.DataBean dataBean = mList.get(groupPosition);
List<MyData.DataBean.SpusBean> spus = dataBean.getSpus();
for (int i = 0; i < spus.size(); i++) {
MyData.DataBean.SpusBean bean = spus.get(i);
if (!bean.isChildChecked()) {
return false;
}
}
return boo;
}
//點擊child給他進行賦值
public void setChildChecked(int groupPosition, int childPosition, boolean isCheckBox) {
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
spusBean.setChildChecked(isCheckBox);
}
//查看當前這個商品有沒有被選中
public boolean isChildChecked(int groupPosition, int childPosition) {
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
if (spusBean.isChildChecked()) {
return true;
}
return false;
}
//給商品數量進行賦值
public void setShangPingNumber(int groupPosition, int childPosition, int number) {
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
spusBean.setPraise_num(number);
}
//因爲咱們底部視圖有個一全選和反選
public boolean isAllGoods() {
boolean boo = true;
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (!spusBean.isChildChecked()) {
boo = false;
}
}
}
return boo;
}
//全選反選
public void setAllGoodsIsChecked(boolean isAllCheck) {
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean bean = dataBean.getSpus().get(j);
bean.setChildChecked(isAllCheck);
}
}
}
//計算所有商品的價格
public float getAllGoodsPrice() {
float allPrice = 0;
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (spusBean.isChildChecked()) {
allPrice += spusBean.getPraise_num() * Float.parseFloat(spusBean.getSkus().get(0).getPrice());
}
}
}
return allPrice;
}
//計算所有商品的數量
public int getAllGoodsNumber() {
int allNumber = 0;
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (spusBean.isChildChecked()) {
allNumber = allNumber + spusBean.getPraise_num();
}
}
}
return allNumber;
}
public interface AdapterCallback {
void setGroupCheck(int groupPosition);
void setChildCheck(int groupPosition, int childPosition);
//點擊加減按鈕刷新
void setNumber(int groupPosition, int childPosition, int number);
}
private AdapterCallback adapterCallback;
public void setCallback(AdapterCallback adapterCallback) {
this.adapterCallback = adapterCallback;
}
}