1. 程式人生 > >安卓仿京東購物車

安卓仿京東購物車

注意:在child_layout.xml裡面的這個元件必須是自己的專案名

需要改一下 直接輸入Add就出來了

<com.bw.gouwuche.AddDeleteView
android:id="@+id/adv_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:left_text="-"
app:middle_text="3"
app:right_text="+"/>

1.導依賴  

compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' compile 'com.facebook.fresco:fresco:0.12.0' compile 'org.greenrobot:eventbus:3.1.1' compile 'io.reactivex.rxjava2:rxjava:2.1.7' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.android.support:recyclerview-v7:23.2.0'

2.加許可權

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

3.配置App

android:name=".app.MyApplication"

4.分包 bean adapter api app model presenter view utils 

delete interceptor  event 這些包

adapter包

package com.bw.jdxiangmu.gouwuchetwo.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
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 android.widget.Toast;
import com.bw.jdxiangmu.R;
import com.bw.jdxiangmu.gouwuchetwo.bean.DatasBean;
import com.bw.jdxiangmu.gouwuchetwo.bean.SomeId;
import com.bw.jdxiangmu.gouwuchetwo.delete.AddDeleteView;
import com.bw.jdxiangmu.gouwuchetwo.event.MessageEvent;
import com.bw.jdxiangmu.gouwuchetwo.event.PriceAndCountEvent;
import com.facebook.drawee.view.SimpleDraweeView;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
/**
 * Created by lenovo on 2018/4/9.
 */
public class MyAdapter extends BaseExpandableListAdapter {
    private Context context;
    private List<DatasBean> groupList;
    private List<List<DatasBean.ListBean>> childList;
    public MyAdapter(Context context, List<DatasBean> groupList, List<List<DatasBean.ListBean>> childList) {
        this.context =context;
        this.groupList = groupList;
        this.childList = childList;
}

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

    @Override
public int getChildrenCount(int i) {
        return childList.get(i).size();
}

    @Override
public Object getGroup(int i) {
        return groupList.get(i);
}

    @Override
public Object getChild(int i, int i1) {
        return childList.get(i).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 false;
}

    @Override
public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) {
        final GroupViewHolder holder;
        if (view == null) {
            holder = new GroupViewHolder();
view = view.inflate(context,R.layout.group_layout, null);
holder.cbGroup = (CheckBox) view.findViewById(R.id.cb_parent);
holder.tv_number = (TextView) view.findViewById(R.id.tv_number);
view.setTag(holder);
} else {
            holder = (GroupViewHolder) view.getTag();
}
        final DatasBean dataBean = groupList.get(i);
holder.cbGroup.setChecked(dataBean.isChecked());
//        holder.tv_number.setText(dataBean.getTitle());
holder.tv_number.setText(dataBean.getSellerName());
//一級checkbox
holder.cbGroup.setOnClickListener(new View.OnClickListener() {
            @Override
public void onClick(View v) {
                dataBean.setChecked(holder.cbGroup.isChecked());
changeChildCbState(i, holder.cbGroup.isChecked());
EventBus.getDefault().post(compute());
changeAllCbState(isAllGroupCbSelected());
notifyDataSetChanged();
}
        });
        return view;
}

    @Override
public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup) {
        final ChildViewHolder holder;
        if (view == null) {
            holder = new ChildViewHolder();
view = view.inflate(context, R.layout.child_layout, null);
holder.cbChild = (CheckBox) view.findViewById(R.id.cb_child);
holder.tv_tel = (TextView) view.findViewById(R.id.tv_tel);
holder.draweeView = (SimpleDraweeView) view.findViewById(R.id.my_image_view);
holder.tv_price = (TextView) view.findViewById(R.id.tv_pri);
holder.tv_del = (TextView) view.findViewById(R.id.tv_del);
holder.adv = (AddDeleteView) view.findViewById(R.id.adv_main);
view.setTag(holder);
} else {
            holder = (ChildViewHolder) view.getTag();
}
        final DatasBean.ListBean datasBean = childList.get(i).get(i1);
holder.cbChild.setChecked(datasBean.isChecked());
holder.tv_tel.setText(datasBean.getTitle());
holder.tv_price.setText("¥"+datasBean.getPrice() );
holder.adv.setNumber(datasBean.getNum());
String images = datasBean.getImages().trim();
String[] split = images.split("\\|");
holder.draweeView.setImageURI(Uri.parse(split[0]));
//二級checkbox
holder.cbChild.setOnClickListener(new View.OnClickListener() {
            @Override
public void onClick(View v) {
                //設定該條目物件裡的checked屬性值
datasBean.setChecked(holder.cbChild.isChecked());
PriceAndCountEvent priceAndCountEvent = compute();
EventBus.getDefault().post(priceAndCountEvent);
                if (holder.cbChild.isChecked()) {
                    //當前checkbox是選中狀態
if (isAllChildCbSelected(i)) {
                        changGroupCbState(i, true);
changeAllCbState(isAllGroupCbSelected());
}
                } else {
                    changGroupCbState(i, false);
changeAllCbState(isAllGroupCbSelected());
}
                notifyDataSetChanged();
}


        });
holder.adv.setOnAddDelClickListener(new AddDeleteView.OnAddDelClickListener() {
            @Override
public void onAddClick(View v) {

                int origin = holder.adv.getNumber();
origin++;
//                holder.adv.setNumber(origin);
int num = datasBean.getNum();
num++;
holder.adv.setNumber(num);
datasBean.setNum(num);
                if (holder.cbChild.isChecked()) {
                    EventBus.getDefault().post(compute());
}
            }

            @Override
public void onDelClick(View v) {
                int origin = holder.adv.getNumber();
//                int num = datasBean.getNum();
origin--;
                if (origin == 0) {
                    Toast.makeText(context,"最小數量為1",Toast.LENGTH_SHORT).show();
                    return ;
}
                holder.adv.setNumber(origin);
datasBean.setNum(origin);
                if (holder.cbChild.isChecked()) {

                    EventBus.getDefault().post(compute());
}

            }
        });
//刪除
holder.tv_del.setOnClickListener(new View.OnClickListener() {

            private AlertDialog dialog;
@Override
public void onClick(View v) {
                final List<DatasBean.ListBean> datasBeen = childList.get(i);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("提示");
builder.setMessage("確認是否刪除?");
builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
public void onClick(DialogInterface dialogInterface, int ii) {
                        DatasBean.ListBean remove = datasBeen.remove(i1);
                        if (datasBeen.size() == 0) {
                            childList.remove(i);
groupList.remove(i);
                            int pid = datasBean.getPid();
SomeId someId = new SomeId();
someId.setPid(pid+"");
EventBus.getDefault().post(someId);
}
                        EventBus.getDefault().post(compute());
notifyDataSetChanged();
}
                });
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
public void onClick(DialogInterface dialogInterface, int i) {
                        dialog.dismiss();
}
                });
dialog = builder.create();
dialog.show();
}
        });
        return view;
}

    @Override
public boolean isChildSelectable(int i, int i1) {
        return false;
}
    class GroupViewHolder {
        CheckBox cbGroup;
TextView tv_number;
}

    class ChildViewHolder {
        CheckBox cbChild;
TextView tv_tel;
TextView tv_content;
TextView tv_time;
//        ImageView imgIcon;
SimpleDraweeView draweeView;
TextView tv_price;
TextView tv_del;
ImageView iv_del;
ImageView iv_add;
TextView tv_num;
AddDeleteView adv;
}
    /**
     * 改變全選的狀態
     *
     * @param flag
*/
private void changeAllCbState(boolean flag) {
        MessageEvent messageEvent = new MessageEvent();
messageEvent.setChecked(flag);
EventBus.getDefault().post(messageEvent);
}
    /**
     * 改變一級列表checkbox狀態
     *
     * @param groupPosition
*/
private void changGroupCbState(int groupPosition, boolean flag) {
//        GoosBean.DataBean dataBean = groupList.get(groupPosition);
DatasBean dataBean = groupList.get(groupPosition);
dataBean.setChecked(flag);
}

    /**
     * 改變二級列表checkbox狀態
     *
     * @param groupPosition
* @param flag
*/
private void changeChildCbState(int groupPosition, boolean flag) {
        List<DatasBean.ListBean> datasBeen = childList.get(groupPosition);
        for (int i = 0; i < datasBeen.size(); i++) {
            DatasBean.ListBean datasBean = datasBeen.get(i);
datasBean.setChecked(flag);
}
    }
    /**
     * 判斷一級列表是否全部選中
     *
     * @return
*/
private boolean isAllGroupCbSelected() {
        for (int i = 0; i < groupList.size(); i++) {
            DatasBean dataBean = groupList.get(i);
            if (!dataBean.isChecked()) {
                return false;
}
        }
        return true;
}

    /**
     * 判斷二級列表是否全部選中
     *
     * @param groupPosition
* @return
*/
private boolean isAllChildCbSelected(int groupPosition) {
        List<DatasBean.ListBean> datasBeen = childList.get(groupPosition);
        for (int i = 0; i < datasBeen.size(); i++) {
            DatasBean.ListBean datasBean = datasBeen.get(i);
            if (!datasBean.isChecked()) {
                return false;
}
        }
        return true;
}
    /**
     * 計算列表中,選中的錢和數量
     */
private PriceAndCountEvent compute() {
        int count = 0;
        int price = 0;
        for (int i = 0; i < childList.size(); i++) {
            List<DatasBean.ListBean> datasBeen = childList.get(i);
            for (int j = 0; j < datasBeen.size(); j++) {
                DatasBean.ListBean datasBean = datasBeen.get(j);
                if (datasBean.isChecked()) {
                    price += datasBean.getNum() * datasBean.getPrice();
count += datasBean.getNum();
}
            }
        }
        PriceAndCountEvent priceAndCountEvent = new PriceAndCountEvent();
priceAndCountEvent.setCount(count);
priceAndCountEvent.setPrice(price);
        return priceAndCountEvent;
}
    /**
     * 設定全選、反選
     *
     * @param flag
*/
public void changeAllListCbState(boolean flag) {
        for (int i = 0; i < groupList.size(); i++) {
            changGroupCbState(i, flag);
changeChildCbState(i, flag);
}
        EventBus.getDefault().post(compute());
notifyDataSetChanged();
}
}

api包

import com.bw.gouwuche.bean.DatasBean;
import com.bw.gouwuche.bean.MessageBean;
import java.util.List;
import io.reactivex.Flowable;
import retrofit2.http.GET;
import retrofit2.http.Query;
/**
 * Created by lenovo on 2018/3/19.
 */
public interface ApiService {

    @GET("product/getCarts")
    Flowable<MessageBean<List<DatasBean>>> getDatas(@Query("uid") String uid);
@GET("product/deleteCart")
    Flowable<MessageBean> deleteData(@Query("uid") String uid, @Query("pid") String pid);
}

app包

importandroid.app.Application;
import com.facebook.drawee.backends.pipeline.Fresco;
public class MyApplication extends Application {
    @Override
public void onCreate() {
        super.onCreate();
Fresco.initialize(this);
}
}

bean包

1.

import java.util.List;
/**
 * Created by lenovo on 2018/3/19.
 */
public class DatasBean {

    /**
     * list : [{"bargainPrice":6666,"createtime":"2017-10-10T16:01:31","detailUrl":"https://item.m.jd.com/product/5089273.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t8284/363/1326459580/71585/6d3e8013/59b857f2N6ca75622.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9346/182/1406837243/282106/68af5b54/59b8480aNe8af7f5c.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8434/54/1359766007/56140/579509d9/59b85801Nfea207db.jpg!q70.jpg","num":1,"pid":46,"price":234,"pscid":39,"selected":0,"sellerid":2,"subhead":"【iPhone新品上市】新一代iPhone,讓智慧看起來更不一樣","title":"Apple iPhone 8 Plus (A1864) 64GB 金色 移動聯通電信4G手機"}]
     * sellerName : 商家2
     * sellerid : 2
     */
private String sellerName;
    private String sellerid;
    private List<ListBean> list;
    private boolean checked;
    public boolean isChecked() {
        return checked;
}

    public void setChecked(boolean checked) {
        this.checked = checked;
}

    public String getSellerName() {
        return sellerName;
}

    public void setSellerName(String sellerName) {
        this.sellerName = sellerName;
}

    public String getSellerid() {
        return sellerid;
}

    public void setSellerid(String sellerid) {
        this.sellerid = sellerid;
}

    public List<ListBean> getList() {
        return list;
}

    public void setList(List<ListBean> list) {
        this.list = list;
}

    public static class ListBean {
        /**
         * bargainPrice : 6666
         * createtime : 2017-10-10T16:01:31
         * detailUrl : https://item.m.jd.com/product/5089273.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends
         * images : https://m.360buyimg.com/n0/jfs/t8284/363/1326459580/71585/6d3e8013/59b857f2N6ca75622.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9346/182/1406837243/282106/68af5b54/59b8480aNe8af7f5c.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8434/54/1359766007/56140/579509d9/59b85801Nfea207db.jpg!q70.jpg
         * num : 1
         * pid : 46
         * price : 234
         * pscid : 39
         * selected : 0
         * sellerid : 2
         * subhead : 【iPhone新品上市】新一代iPhone,讓智慧看起來更不一樣
         * title : Apple iPhone 8 Plus (A1864) 64GB 金色 移動聯通電信4G手機
         */
private boolean checked;
        private double bargainPrice;
        private String createtime;
        private String detailUrl;
        private String images;
        private int num;
        private int pid;
        private double price;
        private int pscid;
        private int selected;
        private int sellerid;
        private String subhead;
        private String title;
        public boolean isChecked() {
            return checked;
}

        public void setChecked(boolean checked) {
            this.checked = checked;
}

        public double getBargainPrice() {
            return bargainPrice;
}

        public void setBargainPrice(double bargainPrice) {
            this.bargainPrice = bargainPrice;
}

        public String getCreatetime() {
            return createtime;
}

        public void setCreatetime(String createtime) {
            this.createtime = createtime;
}

        public String getDetailUrl() {
            return detailUrl;
}

        public void setDetailUrl(String detailUrl) {
            this.detailUrl = detailUrl;
}

        public String getImages() {
            return images;
}

        public void setImages(String images) {
            this.images = images;
}

        public int getNum() {
            return num;
}

        public void setNum(int num) {
            this.num = num;
}

        public int getPid() {
            return pid;
}

        public void setPid(int pid) {
            this.pid = pid;
}

        public double getPrice() {
            return price;
}

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

        public int getPscid() {
            return pscid;
}

        public void setPscid(int pscid) {
            this.pscid = pscid;
}

        public int getSelected() {
            return selected;
}

        public void setSelected(int selected) {
            this.selected = selected;
}

        public int getSellerid() {
            return sellerid;
}

        public void setSellerid(int sellerid) {
            this.sellerid = sellerid;
}

        public String getSubhead() {
            return subhead;
}

        public void setSubhead(String subhead) {
            this.subhead = subhead;
}

        public String getTitle() {
            return title;
}

        public void setTitle(String title) {
            this.title = title;
}
    }
}

2.

public class MessageBean<T> {
    /**
     * msg : 請求成功
     * code : 0
     * data : []
     */
private String msg;
    private String code;
    private T data;
    public String getMsg() {
        return msg;
}

    public void setMsg(String msg) {
        this.msg = msg;
}

    public String getCode() {
        return code;
}

    public void setCode(String code) {
        this.code = code;
}

    public T getData() {
        return data;
}

    public void setData(T data) {
        this.data = data;
}
}

3.

public class SomeId {
    private String pid;
    public String getPid() {
        return pid;
}

    public void setPid(String pid) {
        this.pid = pid;
}
}

model包

1.

import com.bw.gouwuche.bean.MessageBean;
import com.bw.gouwuche.presenter.DelPresenter;
import com.bw.gouwuche.utils.RetrofitUtils;
import io.reactivex.Flowable;
/**
 * Created by lenovo on 2018/3/19.
 */
public class DelModel implements IModel {
    private DelPresenter presenter;
    public DelModel(DelPresenter presenter){
        this.presenter =  presenter;
}
    @Override
public void getData(String uid,String pid) {

        Flowable<MessageBean> delFlowable = RetrofitUtils.getInstance().getApiService().deleteData(uid,pid);
presenter.delData(delFlowable);
}
}

2.

/**
 * Created by lenovo on 2018/3/19.
 */
public interface IModel {
    void getData(String uid, String pid);
}

3.

import com.bw.gouwuche.bean.DatasBean;
import com.bw.gouwuche.bean.MessageBean;
import com.bw.gouwuche.presenter.NewsPresenter;
import com.bw.gouwuche.utils.RetrofitUtils;
import java.util.List;
import io.reactivex.Flowable;
/**
 * Created by lenovo on 2018/3/19.
 */
public class NewsModel  implements IModel{
    private NewsPresenter presenter;
    public NewsModel(NewsPresenter presenter){
        this.presenter = (NewsPresenter) presenter;
}
    @Override
public void getData(String uid,String pid) {
        Flowable<MessageBean<List<DatasBean>>> flowable = RetrofitUtils.getInstance().getApiService().getDatas(uid);
presenter.getNews(flowable);
}
}

presenter包

1.

public interface BasePresenter {
    void getData(String uid, String pid);
}

2.

import com.bw.gouwuche.bean.MessageBean;
import com.bw.gouwuche.model.DelModel;
import com.bw.gouwuche.view.Iview;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subscribers.DisposableSubscriber;
/**
 * Created by lenovo on 2018/3/19.
 */
public class DelPresenter implements BasePresenter {
    private Iview iv;
    private DisposableSubscriber subscriber2;
    public void attachView(Iview iv) {
        this.iv = iv;
}

    public void detachView() {
        if (iv != null) {
            iv = null;
}

        if (!subscriber2.isDisposed()){
            subscriber2.dispose();
}
    }

    @Override
public void getData(String uid,String pid) {
        DelModel model = new DelModel(this);
model.getData(uid,pid);
}



    public void delData(Flowable<MessageBean> delFlowable) {
        subscriber2 = delFlowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableSubscriber<MessageBean>() {
                    @Override
public void onNext(MessageBean listMessageBean) {
                        if (listMessageBean != null) {
                            iv.delSuccess(listMessageBean);
}