MVP+RxJava+Retrofit+二级列表+Evenbus实现二级列表购物车

效果图:



加依赖:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation 'com.google.code.gson:gson:2.8.2'
    implementation 'com.squareup.okhttp3:okhttp:3.9.0'
    implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
    implementation 'org.greenrobot:eventbus:3.1.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
    implementation 'io.reactivex.rxjava2:rxjava:2.0.2'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
    implementation 'com.squareup.retrofit2:retrofit:2.0.2'

}

RetrofitApi:

/**
 * author:Created by WeiWeiFeng on 2018/5/16.
 */
public interface RetrofitApi {
    //https://www.zhaoapi.cn/product/getCarts?uid=13850&source=android"
    @GET("product/getCarts?uid=13850&source=android")
    Observable<Goods> getShoppingData();


}

RetrofitUtils:

public class RetrofitUtils {
    public static RetrofitApi retrofitApi;
    static {
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLogger());
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient().newBuilder()
                .addNetworkInterceptor(logInterceptor)
                //.addInterceptor(new LoggingInterceptor())
                .build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        retrofitApi = retrofit.create(RetrofitApi.class);
    }



    private static class HttpLogger implements HttpLoggingInterceptor.Logger {
        @Override
        public void log(String message) {
            Log.e("TAG", message );
        }
    }


}

BasePresenter:

public class BasePresenter<V extends IBaseView> {
    private V mIBaseView;

    public void attachView(V iBaseView) {
        this.mIBaseView = iBaseView;
    }

    public void detachView() {
        mIBaseView = null;
    }

    public V getView() {
        return mIBaseView;
    }
}

MainPresenter:

public class MainPresenter extends BasePresenter<IMainView> {

    private final HttpUtils httpUtils;

    public MainPresenter() {
        httpUtils = HttpUtils.getHttpUtils();
    }

    @SuppressLint("CheckResult")
    public void getData() {

        Observable<Goods> observable = RetrofitUtils.retrofitApi.getShoppingData();
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Goods>() {
                    @Override
                    public void accept(Goods goods) throws Exception {
                        List<Goods.DataBean> data = goods.getData();
                        getView().onScuess(data);
                    }
                });

    }
}

BaseActivity:

public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements IBaseView{
    public P presenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(setChildView());
        initView();
        initBaseView();
        initData();
    }


    private void initBaseView() {
        presenter = getPresenter();
        if (presenter != null) {
            presenter.attachView(this);
        } else {
            try {
                throw new Exception("出错了");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    protected abstract P getPresenter();

    protected abstract void initView();

    protected abstract int setChildView();

    protected abstract void initData();
}

重点实现购物车

MainActivity:

public class MainActivity extends BaseActivity<MainPresenter> implements IMainView {

    private static final String TAG = "MainActivity";
    private ExpandableListView mElv;
    CheckBox cbSelectAll;
    private TextView tvAllMoney;
    private TextView tvTransport;
    private Button btnSettlement;
    String url = "https://www.zhaoapi.cn/product/getCarts?uid=13850&source=android";
    private MyAdapter adapter;
    private List<Goods.DataBean> data;
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                data = (List<Goods.DataBean>) msg.obj;

                adapter = new MyAdapter(MainActivity.this, data);
                mElv.setAdapter(adapter);
                mElv.setGroupIndicator(null);

                //默认让其全部展开
                for (int i = 0; i < data.size(); i++) {
                    mElv.expandGroup(i);
                }
                adapter.notifyDataSetChanged();
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //注册EventBus
        EventBus.getDefault().register(this);
    }

    @Override
    protected void initData() {
        presenter.getData(url);
    }

    @Override
    protected MainPresenter getPresenter() {
        return new MainPresenter();
    }

    @Override
    protected void initView() {
        mElv = (ExpandableListView) findViewById(R.id.expandableListView);
        cbSelectAll = (CheckBox) findViewById(R.id.cb_select_all);
        tvAllMoney = (TextView) findViewById(R.id.tv_all_money);
        tvTransport = (TextView) findViewById(R.id.tv_transport);
        btnSettlement = (Button) findViewById(R.id.btn_settlement);
        btnSettlement.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, RescudActivity.class);
                startActivity(intent);
            }
        });

        //点击全选按钮
        cbSelectAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                adapter.changeAllListCbState(cbSelectAll.isChecked());
            }
        });
    }

    @Override
    protected int setChildView() {
        return R.layout.activity_main;
    }


    @Override
    public void onScuess(List<Goods.DataBean> data) {
//        Log.e("TAG", "onScuess: "+data.size());
        Message message = handler.obtainMessage();
        message.what = 1;
        message.obj = data;
        handler.sendMessage(message);
    }

    /**
     * 获取传过来的全选状态值
     *
     * @param msg
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getCheckBox(EventMessage msg) {
        boolean name = msg.isChecked();
        cbSelectAll.setChecked(name);
        Log.e(TAG, "getMess: " + name);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(PriceAndCountEvent event) {
        tvAllMoney.setText(event.getPrice() + "");
        btnSettlement.setText("结算(" + event.getCount() + ")");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

Adapter

public class MyAdapter extends BaseExpandableListAdapter {
    private Context context;
    private List<Goods.DataBean> data;

    public MyAdapter(Context context, List<Goods.DataBean> data) {
        this.context = context;
        this.data = data;

    }

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

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

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

    @Override
    public Object getChild(int i, int i1) {
        return data.get(i).getList().get(i1);
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) {
        final ViewHolderGroup group;
        if (view == null) {
            view = View.inflate(context, R.layout.group_item, null);
            group = new ViewHolderGroup();
            group.cb_parent = view.findViewById(R.id.cb_parent);
            group.tv_sign = view.findViewById(R.id.tv_sign);
            view.setTag(group);
        } else {
            group = (ViewHolderGroup) view.getTag();
        }

        group.cb_parent.setChecked(data.get(i).isChecked());
        group.tv_sign.setText(data.get(i).getSellerName());
        //一级Checkbox
        group.cb_parent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                data.get(i).setChecked(group.cb_parent.isChecked());
                changeChildCbState(i, group.cb_parent.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 ViewHolderChild child;
        if (view == null) {
            view = View.inflate(context, R.layout.child, null);
            child = new ViewHolderChild();
            child.cb_child = view.findViewById(R.id.cb_child);
            child.tv_content = view.findViewById(R.id.tv_content);
            child.tv_del = view.findViewById(R.id.tv_del);
            child.tv_num = view.findViewById(R.id.tv_num);
            child.tv_pri = view.findViewById(R.id.tv_pri);
            child.iv_add=view.findViewById(R.id.iv_add);
            child.iv_jian=view.findViewById(R.id.iv_jian);
            view.setTag(child);
        } else {
            child = (ViewHolderChild) view.getTag();
        }

        child.cb_child.setChecked(data.get(i).getList().get(i1).isChildChecked());
        child.tv_content.setText(data.get(i).getList().get(i1).getTitle());
        child.tv_num.setText(data.get(i).getList().get(i1).getNum() + "");
        child.tv_pri.setText(data.get(i).getList().get(i1).getPrice() + "");

        //二级CheckBox
        child.cb_child.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //设置该条目对象里的Checked属性
                data.get(i).getList().get(i1).setChildChecked(child.cb_child.isChecked());

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

                if (child.cb_child.isChecked()) {
                    if (isAllChildCbSelected(i)) {
                        changGroupCbState(i, true);
                        changeAllCbState(isAllGroupCbSelected());
                    }

                } else {
                    changGroupCbState(i, false);
                    changeAllCbState(isAllGroupCbSelected());
                }
                //在此处刷新容易出现小bug  所以改到了changGroupCbState
//                notifyDataSetInvalidated();
            }
        });
        //加号
        child.iv_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int num = data.get(i).getList().get(i1).getNum();
                child.tv_num.setText(++num + "");
                data.get(i).getList().get(i1).setNum(num);
                if (child.cb_child.isChecked()) {
                    PriceAndCountEvent compute = compute();
                    EventBus.getDefault().post(compute);
                }
            }
        });
//        减号
        child.iv_jian.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int num = data.get(i).getList().get(i1).getNum();
                if (num == 0) {
                    return;
                }
                child.tv_num.setText(--num + "");
                data.get(i).getList().get(i1).setNum(num);
                if (child.cb_child.isChecked()) {
                    PriceAndCountEvent compute = compute();
                    EventBus.getDefault().post(compute);
                }
            }
        });

        //删除
        child.tv_del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                data.get(i).getList().remove(i1);
                if (data.get(i).getList().size()==0){
                   data.remove(i);
                }
                EventBus.getDefault().post(compute());
                notifyDataSetInvalidated();
            }
        });

        return view;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }

    class ViewHolderGroup {
        private CheckBox cb_parent;
        private TextView tv_sign;
    }

    class ViewHolderChild {
        private CheckBox cb_child;
        private TextView tv_content, tv_pri, tv_num, tv_del;
        private ImageView iv_add, iv_jian;
    }

    /**
     * 改变全选按钮
     *
     * @param fla
     */

    private void changeAllCbState(boolean fla) {
        EventMessage eventMessage = new EventMessage();
        eventMessage.setChecked(fla);
        EventBus.getDefault().post(eventMessage);
    }


    /**
     * 改变一级列表checkbox状态
     *
     * @param groupPosition
     */
    private void changGroupCbState(int groupPosition, boolean flag) {
        Goods.DataBean dataBean = data.get(groupPosition);
        dataBean.setChecked(flag);
        notifyDataSetChanged();
    }


    /**
     * 点击一级列表的CheckBox
     * 改变二级列表CheckBox状态
     *
     * @param i
     * @param flag
     */
    private void changeChildCbState(int i, boolean flag) {
        List<Goods.DataBean.ListBean> list = data.get(i).getList();
        for (int j = 0; j < list.size(); j++) {
            Goods.DataBean.ListBean listBean = list.get(j);
            listBean.setChildChecked(flag);
        }
    }

    /**
     * 判断所有的一级checkbox是否全选
     *
     * @return
     */

    private boolean isAllGroupCbSelected() {
        for (int i = 0; i < data.size(); i++) {
            Goods.DataBean dataBean = data.get(i);
            if (!dataBean.isChecked()) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断所有的二级checkbox是否全选
     *
     * @param groupPosition
     * @return
     */
    private boolean isAllChildCbSelected(int groupPosition) {
        List<Goods.DataBean.ListBean> list = data.get(groupPosition).getList();
        for (int i = 0; i < list.size(); i++) {
            Goods.DataBean.ListBean listBean = list.get(i);
            if (!listBean.isChildChecked()) {
                return false;
            }
        }

        return true;
    }

    /**
     * 计算选中的价钱和数量
     */
    private PriceAndCountEvent compute() {
        int count = 0;
        int price = 0;
        for (int i = 0; i <data.size(); i++) {
            List<Goods.DataBean.ListBean> list = data.get(i).getList();
            for (int j = 0; j < list.size(); j++) {
                Goods.DataBean.ListBean listBean = list.get(j);
                if (listBean.isChildChecked()){
                    count+=listBean.getNum();
                    price+=listBean.getNum()*listBean.getPrice();
                }
            }


        }
        PriceAndCountEvent priceAndCountEvent = new PriceAndCountEvent();
        priceAndCountEvent.setPrice(price);
        priceAndCountEvent.setCount(count);
        return priceAndCountEvent;
    }


    /**
     * 设置反选全选
     *
     * @param flag
     */

    public void changeAllListCbState(boolean flag) {
        for (int i = 0; i < data.size(); i++) {
            changGroupCbState(i, flag);
            changeChildCbState(i, flag);
        }
        EventBus.getDefault().post(compute());
        notifyDataSetChanged();
    }

}

//布局文件

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".view.activity.MainActivity">

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

        />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="49dp"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:orientation="horizontal">

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

group_item.xml

<?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="100dp"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <CheckBox
        android:id="@+id/cb_parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="30dp"
        android:focusable="false" />

    <TextView
        android:id="@+id/tv_sign"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="标记" />



</LinearLayout>

child.xml


<?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:background="@android:color/darker_gray"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <CheckBox

        android:id="@+id/cb_child"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp"
        android:layout_marginLeft="40dp"
        android:layout_marginTop="30dp"
   />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <TextView
            android:id="@+id/tv_content"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginLeft="20dp"
            android:text="什么手机" />


    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_pri"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:text="¥3000.00" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical">

            <ImageView
                android:id="@+id/iv_jian"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:src="@drawable/jian" />

            <TextView
                android:id="@+id/tv_num"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:paddingBottom="2dp"
                android:paddingLeft="20dp"
                android:paddingRight="20dp"
                android:paddingTop="2dp"
                android:text="1" />

            <ImageView
                android:id="@+id/iv_add"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginLeft="5dp"
                android:src="@drawable/jia" />

        </LinearLayout>

    </LinearLayout>

    <TextView
        android:id="@+id/tv_del"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="删除" />
</LinearLayout>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值