购物车+二级列表

本文详细介绍了一款购物车应用的界面布局与交互设计,包括主活动布局文件、自定义复选框组件、购物车子项及分组布局等。通过自定义组件实现了平滑动画效果,并介绍了如何通过监听器实现购物车商品选择、数量增减等功能。
摘要由CSDN通过智能技术生成


布局======================================================================

mian_activity==============================================================

<?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>

include_toolbar================================================================

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:background="@color/colorPrimary"
    android:gravity="center"
    android:minHeight="48dp">

    <TextView
        android:id="@+id/tv_toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="购物车"
        android:textColor="@android:color/white"
        android:textSize="19sp" />

</android.support.v7.widget.Toolbar>

item_shopingcart_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="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>

item_shopingcart_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="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>

values.attrs==================================================================

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="SmoothCheckBox">
        <attr name="duration" format="integer"/>
        <attr name="stroke_width" format="dimension"/>
        <attr name="color_tick" format="color"/>
        <attr name="color_checked" format="color"/>
        <attr name="color_unchecked" format="color"/>
        <attr name="color_unchecked_stroke" format="color"/>
    </declare-styleable>
</resources>

bg_4stroke_grey=================================================================

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="2dp" />
    <solid android:color="#00FFFFFF" />
    <stroke
        android:width="1dp"
        android:color="#CCCCCC" />

</shape>

seletor_shopping_cart_add=======================================================

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_shopping_cart_add_press" android:state_checked="true" />
    <item android:drawable="@drawable/btn_shopping_cart_add_press" android:state_pressed="true" />
    <item android:drawable="@drawable/btn_shopping_cart_add_press" android:state_selected="true" />
    <item android:drawable="@drawable/btn_shopping_cart_add_normal" />
</selector>

selector_shopping_cart_subtract=====================================================

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_shopping_cart_add_press" android:state_checked="true" />
    <item android:drawable="@drawable/btn_shopping_cart_add_press" android:state_pressed="true" />
    <item android:drawable="@drawable/btn_shopping_cart_add_press" android:state_selected="true" />
    <item android:drawable="@drawable/btn_shopping_cart_add_normal" />
</selector>

MianActivity================================================================

package com.xp.shoppingcart;

import android.app.Activity;
import android.content.res.AssetManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MainActivity extends AppCompatActivity implements UpdateView, View.OnClickListener {

    private ExpandableListView mExpandableListView;
    private SmoothCheckBox mCbSelectAll;
    private TextView mTvAllMoney;
    private Button mBtnBuy;
    StringBuffer stringBuffer;
    GoodBean goodBean;
    ExpandableListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        initEvent();
    }

    private void initEvent() {
        mCbSelectAll.setOnClickListener(this);
    }

    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);
        }
    }

    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) {

            }
        });

    }

    @Override
    public void update(boolean isAllSelected, int count, int price) {
        mBtnBuy.setText("结算(" + count + ")");
        mTvAllMoney.setText("¥" + price);
        mCbSelectAll.setChecked(isAllSelected);
    }

    @Override
    public void onClick(View view) {
        selectAll();
    }

    private void selectAll() {
        int allCount = goodBean.getAllCount();
        int allMoney = goodBean.getAllMoney();
        if (!mCbSelectAll.isChecked()) {
            goodBean.setAllSelect(true);
            for (int i = 0; i < goodBean.getContent().size(); i++) {
                goodBean.getContent().get(i).setIsSelected(true);
                for (int n = 0; n < goodBean.getContent().get(i).getGoodDetail().size(); n++) {
                    if (!goodBean.getContent().get(i).getGoodDetail().get(n).isSelected()) {
                        allCount++;
                        allMoney += Integer.valueOf(goodBean.getContent().get(i).getGoodDetail().get(n).getCount())
                                * Integer.valueOf(goodBean.getContent().get(i).getGoodDetail().get(n).getPrice());
                        goodBean.getContent().get(i).getGoodDetail().get(n).setIsSelected(true);
                    }
                }
            }
        } else {
            goodBean.setAllSelect(false);
            for (int i = 0; i < goodBean.getContent().size(); i++) {
                goodBean.getContent().get(i).setIsSelected(false);
                for (int n = 0; n < goodBean.getContent().get(i).getGoodDetail().size(); n++) {
                    goodBean.getContent().get(i).getGoodDetail().get(n).setIsSelected(false);
                }
                allCount = 0;
                allMoney = 0;
            }
        }
        goodBean.setAllMoney(allMoney);
        goodBean.setAllCount(allCount);
        update(goodBean.isAllSelect(), allCount, allMoney);
        mAdapter.notifyDataSetChanged();
    }
}

SmoothCheckBox==============================================================

package com.xp.shoppingcart;

import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Checkable;

/**
 * Description : A custom CheckBox with animation for Android
 */

public class SmoothCheckBox extends View implements Checkable {
    private static final String KEY_INSTANCE_STATE = "InstanceState";

    private static final int COLOR_TICK = Color.WHITE;
    private static final int COLOR_UNCHECKED = Color.WHITE;
    private static final int COLOR_CHECKED = Color.parseColor("#FB4846");
    private static final int COLOR_FLOOR_UNCHECKED = Color.parseColor("#DFDFDF");

    private static final int DEF_DRAW_SIZE = 25;
    private static final int DEF_ANIM_DURATION = 300;

    private Paint mPaint, mTickPaint, mFloorPaint;
    private Point[] mTickPoints;
    private Point mCenterPoint;
    private Path mTickPath;


    private float mLeftLineDistance, mRightLineDistance, mDrewDistance;
    private float mScaleVal = 1.0f, mFloorScale = 1.0f;
    private int mWidth, mAnimDuration, mStrokeWidth;
    private int mCheckedColor, mUnCheckedColor, mFloorColor, mFloorUnCheckedColor;

    private boolean mChecked;
    private boolean mTickDrawing;
    private OnCheckedChangeListener mListener;

    public SmoothCheckBox(Context context) {
        this(context, null);
    }

    public SmoothCheckBox(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SmoothCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet attrs) {

        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.SmoothCheckBox);
        int tickColor = ta.getColor(R.styleable.SmoothCheckBox_color_tick, COLOR_TICK);
        mAnimDuration = ta.getInt(R.styleable.SmoothCheckBox_duration, DEF_ANIM_DURATION);
        mFloorColor = ta.getColor(R.styleable.SmoothCheckBox_color_unchecked_stroke, COLOR_FLOOR_UNCHECKED);
        mCheckedColor = ta.getColor(R.styleable.SmoothCheckBox_color_checked, COLOR_CHECKED);
        mUnCheckedColor = ta.getColor(R.styleable.SmoothCheckBox_color_unchecked, COLOR_UNCHECKED);
        mStrokeWidth = ta.getDimensionPixelSize(R.styleable.SmoothCheckBox_stroke_width, TextSizeUtils.dip2px(getContext(), 0));
        ta.recycle();

        mFloorUnCheckedColor = mFloorColor;
        mTickPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTickPaint.setStyle(Paint.Style.STROKE);
        mTickPaint.setStrokeCap(Paint.Cap.ROUND);
        mTickPaint.setColor(tickColor);

        mFloorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mFloorPaint.setStyle(Paint.Style.FILL);
        mFloorPaint.setColor(mFloorColor);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(mCheckedColor);

        mTickPath = new Path();
        mCenterPoint = new Point();
        mTickPoints = new Point[3];
        mTickPoints[0] = new Point();
        mTickPoints[1] = new Point();
        mTickPoints[2] = new Point();

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                toggle();
                mTickDrawing = false;
                mDrewDistance = 0;
                if (isChecked()) {
                    startCheckedAnimation();
                } else {
                    startUnCheckedAnimation();
                }
            }
        });
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(KEY_INSTANCE_STATE, super.onSaveInstanceState());
        bundle.putBoolean(KEY_INSTANCE_STATE, isChecked());
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            boolean isChecked = bundle.getBoolean(KEY_INSTANCE_STATE);
            setChecked(isChecked);
            super.onRestoreInstanceState(bundle.getParcelable(KEY_INSTANCE_STATE));
            return;
        }
        super.onRestoreInstanceState(state);
    }

    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void toggle() {
        this.setChecked(!isChecked());
    }

    @Override
    public void setChecked(boolean checked) {
        mChecked = checked;
        reset();
        invalidate();
        if (mListener != null) {
            mListener.onCheckedChanged(SmoothCheckBox.this, mChecked);
        }
    }

    /**
     * checked with animation
     *
     * @param checked checked
     * @param animate change with animation
     */
    public void setChecked(boolean checked, boolean animate) {
        if (animate) {
            mTickDrawing = false;
            mChecked = checked;
            mDrewDistance = 0f;
            if (checked) {
                startCheckedAnimation();
            } else {
                startUnCheckedAnimation();
            }
            if (mListener != null) {
                mListener.onCheckedChanged(SmoothCheckBox.this, mChecked);
            }

        } else {
            this.setChecked(checked);
        }
    }

    private void reset() {
        mTickDrawing = true;
        mFloorScale = 1.0f;
        mScaleVal = isChecked() ? 0f : 1.0f;
        mFloorColor = isChecked() ? mCheckedColor : mFloorUnCheckedColor;
        mDrewDistance = isChecked() ? (mLeftLineDistance + mRightLineDistance) : 0;
    }

    private int measureSize(int measureSpec) {
        int defSize = TextSizeUtils.dip2px(getContext(), DEF_DRAW_SIZE);
        int specSize = MeasureSpec.getSize(measureSpec);
        int specMode = MeasureSpec.getMode(measureSpec);

        int result = 0;
        switch (specMode) {
            case MeasureSpec.UNSPECIFIED:
            case MeasureSpec.AT_MOST:
                result = Math.min(defSize, specSize);
                break;
            case MeasureSpec.EXACTLY:
                result = specSize;
                break;
        }
        return result;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureSize(widthMeasureSpec), measureSize(heightMeasureSpec));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        mWidth = getMeasuredWidth();
        mStrokeWidth = (mStrokeWidth == 0 ? getMeasuredWidth() / 10 : mStrokeWidth);
        mStrokeWidth = mStrokeWidth > getMeasuredWidth() / 5 ? getMeasuredWidth() / 5 : mStrokeWidth;
        mStrokeWidth = (mStrokeWidth < 3) ? 3 : mStrokeWidth;
        mCenterPoint.x = mWidth / 2;
        mCenterPoint.y = getMeasuredHeight() / 2;

        mTickPoints[0].x = Math.round((float) getMeasuredWidth() / 30 * 7);
        mTickPoints[0].y = Math.round((float) getMeasuredHeight() / 30 * 14);
        mTickPoints[1].x = Math.round((float) getMeasuredWidth() / 30 * 13);
        mTickPoints[1].y = Math.round((float) getMeasuredHeight() / 30 * 20);
        mTickPoints[2].x = Math.round((float) getMeasuredWidth() / 30 * 22);
        mTickPoints[2].y = Math.round((float) getMeasuredHeight() / 30 * 10);

        mLeftLineDistance = (float) Math.sqrt(Math.pow(mTickPoints[1].x - mTickPoints[0].x, 2) +
                Math.pow(mTickPoints[1].y - mTickPoints[0].y, 2));
        mRightLineDistance = (float) Math.sqrt(Math.pow(mTickPoints[2].x - mTickPoints[1].x, 2) +
                Math.pow(mTickPoints[2].y - mTickPoints[1].y, 2));
        mTickPaint.setStrokeWidth(mStrokeWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawBorder(canvas);
        drawCenter(canvas);
        drawTick(canvas);
    }

    private void drawCenter(Canvas canvas) {
        mPaint.setColor(mUnCheckedColor);
        float radius = (mCenterPoint.x - mStrokeWidth) * mScaleVal;
        canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, radius, mPaint);
    }

    private void drawBorder(Canvas canvas) {
        mFloorPaint.setColor(mFloorColor);
        int radius = mCenterPoint.x;
        canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, radius * mFloorScale, mFloorPaint);
    }

    private void drawTick(Canvas canvas) {
        if (mTickDrawing && isChecked()) {
            drawTickPath(canvas);
        }
    }

    private void drawTickPath(Canvas canvas) {
        mTickPath.reset();
        // draw left of the tick
        if (mDrewDistance < mLeftLineDistance) {
            float step = (mWidth / 20.0f) < 3 ? 3 : (mWidth / 20.0f);
            mDrewDistance += step;
            float stopX = mTickPoints[0].x + (mTickPoints[1].x - mTickPoints[0].x) * mDrewDistance / mLeftLineDistance;
            float stopY = mTickPoints[0].y + (mTickPoints[1].y - mTickPoints[0].y) * mDrewDistance / mLeftLineDistance;

            mTickPath.moveTo(mTickPoints[0].x, mTickPoints[0].y);
            mTickPath.lineTo(stopX, stopY);
            canvas.drawPath(mTickPath, mTickPaint);

            if (mDrewDistance > mLeftLineDistance) {
                mDrewDistance = mLeftLineDistance;
            }
        } else {

            mTickPath.moveTo(mTickPoints[0].x, mTickPoints[0].y);
            mTickPath.lineTo(mTickPoints[1].x, mTickPoints[1].y);
            canvas.drawPath(mTickPath, mTickPaint);

            // draw right of the tick
            if (mDrewDistance < mLeftLineDistance + mRightLineDistance) {
                float stopX = mTickPoints[1].x + (mTickPoints[2].x - mTickPoints[1].x) * (mDrewDistance - mLeftLineDistance) / mRightLineDistance;
                float stopY = mTickPoints[1].y - (mTickPoints[1].y - mTickPoints[2].y) * (mDrewDistance - mLeftLineDistance) / mRightLineDistance;

                mTickPath.reset();
                mTickPath.moveTo(mTickPoints[1].x, mTickPoints[1].y);
                mTickPath.lineTo(stopX, stopY);
                canvas.drawPath(mTickPath, mTickPaint);

                float step = (mWidth / 20) < 3 ? 3 : (mWidth / 20);
                mDrewDistance += step;
            } else {
                mTickPath.reset();
                mTickPath.moveTo(mTickPoints[1].x, mTickPoints[1].y);
                mTickPath.lineTo(mTickPoints[2].x, mTickPoints[2].y);
                canvas.drawPath(mTickPath, mTickPaint);
            }
        }

        // invalidate
        if (mDrewDistance < mLeftLineDistance + mRightLineDistance) {
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    postInvalidate();
                }
            }, 10);
        }
    }

    private void startCheckedAnimation() {
        ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0f);
        animator.setDuration(mAnimDuration / 3 * 2);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mScaleVal = (float) animation.getAnimatedValue();
                mFloorColor = getGradientColor(mUnCheckedColor, mCheckedColor, 1 - mScaleVal);
                postInvalidate();
            }
        });
        animator.start();

        ValueAnimator floorAnimator = ValueAnimator.ofFloat(1.0f, 0.8f, 1.0f);
        floorAnimator.setDuration(mAnimDuration);
        floorAnimator.setInterpolator(new LinearInterpolator());
        floorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mFloorScale = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        floorAnimator.start();

        drawTickDelayed();
    }

    private void startUnCheckedAnimation() {
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1.0f);
        animator.setDuration(mAnimDuration);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mScaleVal = (float) animation.getAnimatedValue();
                mFloorColor = getGradientColor(mCheckedColor, mFloorUnCheckedColor, mScaleVal);
                postInvalidate();
            }
        });
        animator.start();

        ValueAnimator floorAnimator = ValueAnimator.ofFloat(1.0f, 0.8f, 1.0f);
        floorAnimator.setDuration(mAnimDuration);
        floorAnimator.setInterpolator(new LinearInterpolator());
        floorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mFloorScale = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        floorAnimator.start();
    }

    private void drawTickDelayed() {
        postDelayed(new Runnable() {
            @Override
            public void run() {
                mTickDrawing = true;
                postInvalidate();
            }
        }, mAnimDuration);
    }

    private static int getGradientColor(int startColor, int endColor, float percent) {
        int startA = Color.alpha(startColor);
        int startR = Color.red(startColor);
        int startG = Color.green(startColor);
        int startB = Color.blue(startColor);

        int endA = Color.alpha(endColor);
        int endR = Color.red(endColor);
        int endG = Color.green(endColor);
        int endB = Color.blue(endColor);

        int currentA = (int) (startA * (1 - percent) + endA * percent);
        int currentR = (int) (startR * (1 - percent) + endR * percent);
        int currentG = (int) (startG * (1 - percent) + endG * percent);
        int currentB = (int) (startB * (1 - percent) + endB * percent);
        return Color.argb(currentA, currentR, currentG, currentB);
    }

    public void setOnCheckedChangeListener(OnCheckedChangeListener l) {
        this.mListener = l;
    }

    public interface OnCheckedChangeListener {
        void onCheckedChanged(SmoothCheckBox checkBox, boolean isChecked);
    }
}

TextSizeUtiles==================================================================

package com.xp.shoppingcart;

import android.content.Context;


public class TextSizeUtils {
    /**
     * 将px值转换为dip或dp值,保证尺寸大小不变
     *
     * @param pxValue (DisplayMetrics类中属性density)
     * @return
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 将dip或dp值转换为px值,保证尺寸大小不变
     *
     * @param dipValue (DisplayMetrics类中属性density)
     * @return
     */
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    /**
     * 将px值转换为sp值,保证文字大小不变
     *
     * @param pxValue (DisplayMetrics类中属性scaledDensity)
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    /**
     * 将sp值转换为px值,保证文字大小不变
     *
     * @param spValue (DisplayMetrics类中属性scaledDensity)
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}

UpdateView================================================================

package com.xp.shoppingcart;

/**
 * 更新数据的回调接口
 */
public interface UpdateView {
    void update(boolean isAllSelected, int count, int price);
}

ExpandableListAdapter=============================================================

package com.xp.shoppingcart;

import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private static final String TAG = "ExpandableListAdapter";
    private Context mContext;
    private GoodBean goodBean;
    private UpdateView updateViewListener;
    protected static final int KEY_DATA = 0xFFF11133;

    public ExpandableListAdapter(Context context, GoodBean goodBean) {
        this.mContext = context;
        this.goodBean = goodBean;
    }

    @Override
    public int getGroupCount() {
        return goodBean.getContent().size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return goodBean.getContent().get(groupPosition).getGoodDetail().size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return goodBean.getContent().get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return goodBean.getContent().get(groupPosition).getGoodDetail().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;
    }

    @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;
    }

    @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;

    }

    /**
     * 商品数量EditText内容改变的监听
     */
    class EditTextWatcher implements TextWatcher {

        private GoodBean.ContentBean.GoodDetailBean GoodDetail;

        public EditTextWatcher(GoodBean.ContentBean.GoodDetailBean item) {
            this.GoodDetail = item;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (!TextUtils.isEmpty(s.toString().trim())) {
                String textNum = s.toString().trim();
                GoodDetail.setCount(textNum);
            }
        }
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SmoothCheckBox checkBox;
            String tag = v.getTag().toString();
            String[] split;
            int groupId = 0;
            int childId = 0;
            int childSize = 0;
            int groupPosition = 0;
            int allCount = goodBean.getAllCount();//被选中的item数量
            int allMoney = goodBean.getAllMoney();
            if (tag.contains(",")) {
                split = tag.split(",");
                groupId = Integer.parseInt(split[0]);
                childId = Integer.parseInt(split[1]);
            } else {
                groupPosition = Integer.parseInt(tag);
                childSize = goodBean.getContent().get(groupPosition).getGoodDetail().size();
            }
            switch (v.getId()) {
                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;
                //单个子项item被点击
                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;
                case R.id.tv_reduce:
                    //减少商品数量
                    String goodCount = goodBean.getContent().get(groupId).getGoodDetail().get(childId).getCount();
                    if (Integer.valueOf(goodCount) > 1) {
                        goodBean.getContent().get(groupId).getGoodDetail().get(childId).setCount(reduceCount(goodCount));
                        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();
                    }
                    break;
                case R.id.img_delete:
                    goodBean.getContent().get(groupId).getGoodDetail().remove(childId);
                    if (goodBean.getContent().get(groupId).getGoodDetail().size() == 0) {
                        goodBean.getContent().remove(groupId);
                    }
                    notifyDataSetChanged();
                    break;
            }
        }
    };

    public void setChangedListener(UpdateView listener) {
        if (updateViewListener == null) {
            this.updateViewListener = listener;
        }
    }

    private String addCount(String var) {
        Integer integer = Integer.valueOf(var);
        integer++;
        return integer + "";
    }

    private String reduceCount(String var) {
        Integer integer = Integer.valueOf(var);
        if (integer > 1) {
            integer--;
        }
        return integer + "";
    }

    static class GroupViewHolder {
        SmoothCheckBox cbGroupItem;
        TextView tvPosition;

        GroupViewHolder(View view) {
            cbGroupItem = (SmoothCheckBox) view.findViewById(R.id.cb_group_item);
            tvPosition = (TextView) view.findViewById(R.id.tv_position);
        }
    }

    static class ChildViewHolder {
        SmoothCheckBox cbItem;
        TextView tvPrice,tvGoodName;
        EditText etCount;
        TextView tvReduce;
        TextView tvAdd;
        ImageView imgDelete;
        ImageView imgIcon;

        ChildViewHolder(View view) {
            cbItem = (SmoothCheckBox) view.findViewById(R.id.cb_item);
            tvPrice = (TextView) view.findViewById(R.id.tv_price);
            tvGoodName = (TextView) view.findViewById(R.id.tv_good_name);
            etCount = (EditText) view.findViewById(R.id.et_count);
            tvReduce = (TextView) view.findViewById(R.id.tv_reduce);
            tvAdd = (TextView) view.findViewById(R.id.tv_add);
            imgDelete = (ImageView) view.findViewById(R.id.img_delete);
            imgIcon = (ImageView) view.findViewById(R.id.img_icon);
        }
    }
}

GoodBean====================================================================

package com.xp.shoppingcart;

import java.util.List;

public class GoodBean {

    private List<ContentBean> content;
    private int allMoney;
    private int allCount;
    private boolean isAllSelect;

    public boolean isAllSelect() {
        return isAllSelect;
    }

    public void setAllSelect(boolean allSelect) {
        isAllSelect = allSelect;
    }

    public int getAllMoney() {
        return allMoney;
    }

    public void setAllMoney(int allMoney) {
        this.allMoney = allMoney;
    }

    public int getAllCount() {
        return allCount;
    }

    public void setAllCount(int allCount) {
        this.allCount = allCount;
    }

    public List<ContentBean> getContent() {
        return content;
    }

    public void setContent(List<ContentBean> content) {
        this.content = content;
    }

    public static class ContentBean {
        private String id;
        private String address;
        private boolean isSelected;

        private List<GoodDetailBean> goodDetail;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getAddress() {
            return address;
        }

        public void setAdress(String address) {
            this.address = address;
        }

        public boolean isSelected() {
            return isSelected;
        }

        public void setIsSelected(boolean isSelected) {
            this.isSelected = isSelected;
        }

        public List<GoodDetailBean> getGoodDetail() {
            return goodDetail;
        }

        public void setGoodDetail(List<GoodDetailBean> goodDetail) {
            this.goodDetail = goodDetail;
        }

        public static class GoodDetailBean {
            private String id;
            private String pic;
            private String count;
            private String name;
            private String price;
            private boolean isEdit;
            private boolean isSelected;

            public boolean isEdit() {
                return isEdit;
            }

            public boolean isSelected() {
                return isSelected;
            }

            public void setIsSelected(boolean isSelected) {
                this.isSelected = isSelected;
            }

            public String getId() {
                return id;
            }

            public void setId(String id) {
                this.id = id;
            }

            public String getPic() {
                return pic;
            }

            public void setPic(String pic) {
                this.pic = pic;
            }

            public String getCount() {
                return count;
            }

            public void setCount(String count) {
                this.count = count;
            }


            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getPrice() {
                return price;
            }

            public void setPrice(String price) {
                this.price = price;
            }

            public boolean isIsedit() {
                return isEdit;
            }

            public void setIsEdit(boolean isEdit) {
                this.isEdit = isEdit;
            }
        }
    }
}

依赖======================================================================

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "26.0.2"
    defaultConfig {
        applicationId "com.xp.shoppingcart"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.google.code.gson:gson:2.2.4'
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值