使用的依赖和权限
<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"/>
implementation rootProject.ext.dependencies["appcompat-v7"] implementation rootProject.ext.dependencies["constraint-layout"] implementation rootProject.ext.dependencies["retrofit2"] implementation rootProject.ext.dependencies["converter-gson"] implementation rootProject.ext.dependencies["rxjava2"] implementation rootProject.ext.dependencies["rxjava2:rxandroid"] implementation rootProject.ext.dependencies["dagger"] annotationProcessor rootProject.ext.dependencies["dagger-compiler"] implementation rootProject.ext.dependencies["adapter-rxjava"] //fresco implementation 'com.facebook.fresco:fresco:0.12.0' // 支持 GIF 动图,需要添加 implementation 'com.facebook.fresco:animated-gif:0.12.0' implementation 'com.android.support:support-v4:27.1.1' //butterknife implementation 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' //recyclerview implementation 'com.android.support:recyclerview-v7:27.1.1' //gilde implementation 'com.github.bumptech.glide:glide:4.7.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1' //design implementation 'com.android.support:design:27.1.1' //banner implementation 'com.youth.banner:banner:1.4.10' implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
build.gradle
apply from: "config.gradle"
config.gradle
ext { android = [ compileSdkVersion: 27, applicationId : "com.bwie.test.shoppingcart", minSdkVersion : 15, targetSdkVersion : 27, versionCode : 1, versionName : "1.0" ] dependencies = [ "appcompat-v7" : "com.android.support:appcompat-v7:27.1.1", "constraint-layout": "com.android.support.constraint:constraint-layout:1.1.0", "retrofit2" : "com.squareup.retrofit2:retrofit:2.4.0", "converter-gson" : "com.squareup.retrofit2:converter-gson:2.4.0", "adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava2:2.4.0", "rxjava2" : "io.reactivex.rxjava2:rxjava:2.1.13", "rxjava2:rxandroid": "io.reactivex.rxjava2:rxandroid:2.0.2", "dagger" : "com.google.dagger:dagger:2.8", "dagger-compiler" : "com.google.dagger:dagger-compiler:2.7" ] }
activity_shopping_cart
<?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=".ShoppingCartActivity"> <TextView android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:text="购物车"/> <ExpandableListView android:id="@+id/elv" android:groupIndicator="@null" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> </ExpandableListView> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp"> <CheckBox android:id="@+id/cbAll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="全选"/> <TextView android:id="@+id/tvMoney" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_toRightOf="@id/cbAll" android:text="合计:"/> <TextView android:id="@+id/tvTotal" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="10dp" android:paddingRight="10dp" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:textColor="#ffffff" android:background="#ff0000" android:gravity="center" android:layout_marginLeft="10dp" android:text="去结算:"/> </RelativeLayout> </LinearLayout>
add_sub_view
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/child_image" android:layout_marginRight="5dp" android:layout_toLeftOf="@+id/child_text_delete" android:orientation="horizontal"> <TextView android:id="@+id/child_text_jian" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/cart_biankuang" android:padding="5dp" android:text="-"/> <TextView android:id="@+id/child_text_num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/cart_biankuang" android:paddingBottom="5dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="5dp"/> <TextView android:id="@+id/child_text_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/cart_biankuang" android:padding="5dp" android:text="+"/> </LinearLayout>
shopcart_seller_item
<?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="30dp" android:gravity="center_vertical" android:orientation="horizontal"> <CheckBox android:id="@+id/cbSeller" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp"/> <TextView android:id="@+id/tvSeller" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp"/> </LinearLayout>
shopcart_seller_product_item
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <CheckBox android:id="@+id/cbProduct" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp"/> <TextView android:id="@+id/tvDel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="15dp" android:background="#ff0000" android:gravity="center_vertical" android:text="删除" android:textColor="#ffffff"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/tvDel" android:layout_toRightOf="@id/cbProduct" android:orientation="horizontal"> <ImageView android:id="@+id/iv" android:layout_width="70dp" android:layout_height="70dp" android:layout_gravity="center_vertical"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:orientation="vertical"> <TextView android:id="@+id/tvTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tvPrice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="12312" android:textColor="#ff0000"/> <com.bwie.test.utils.AddSubView android:id="@+id/addSubCard" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true"> </com.bwie.test.utils.AddSubView> </RelativeLayout> </LinearLayout> </LinearLayout> </RelativeLayout>
drawable文件夹下cart_biankuang
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#ffffff" /> <stroke android:width="0.1dp" android:color="#000000" /> </shape>
ShoppingCartActivity
import android.app.ProgressDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.CheckBox; import android.widget.ExpandableListView; import android.widget.TextView; import com.bwie.test.adapter.ShopcartAdapter; import com.bwie.test.bean.GetCartsBean; import com.bwie.test.bean.SellerBean; import com.bwie.test.component.DaggerHttpComponent; import com.bwie.test.shoppingcart.base.BaseActivity; import com.bwie.test.shoppingcart.contract.ShopcartContract; import com.bwie.test.shoppingcart.presenter.ShopcartPresenter; import com.bwie.test.utils.DialogUtil; import java.util.List; public class ShoppingCartActivity extends BaseActivity<ShopcartPresenter> implements ShopcartContract.View { private ExpandableListView mElv; /** * 全选 */ private CheckBox mCbAll; /** * 合计: */ private TextView mTvMoney; /** * 去结算: */ private TextView mTvTotal; private ProgressDialog progressDialog; private ShopcartAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shopping_cart); initView(); //请求购物车接口 mPresenter.getCarts(getUid(), getToken()); progressDialog = DialogUtil.getProgressDialog(this); } @Override public int getContentLayout() { return R.layout.activity_shopping_cart; } @Override public void inject() { DaggerHttpComponent.builder() .build() .inject(this); } @Override public void showCartList(List<SellerBean> groupList, List<List<GetCartsBean.DataBean.ListBean>> childList) { adapter = new ShopcartAdapter( this, groupList, childList, progressDialog, mPresenter ); //判断所有商家是否都选中,如果都选中则把全选设置为true if (adapter != null) { mCbAll.setChecked(adapter.isAllSelected()); } mElv.setAdapter(adapter); //展开列表 for (int i = 0; i < groupList.size(); i++) { mElv.expandGroup(i); } if (adapter != null) { String[] moneyAndCount = adapter.getMoneyAndCount(); mTvMoney.setText("总计:" + moneyAndCount[0] + "元"); mTvTotal.setText("总共(" + moneyAndCount[1] + ")个"); } } @Override public void updateCartsSuccess(String msg) { if(adapter != null){ adapter.updateSuceess(); } } @Override public void deleteCartSuccess(String msg) { //调用适配器里的delSuccess()方法 if (adapter != null){ adapter.delSuccess(); } } private void initView() { mElv = (ExpandableListView) findViewById( R.id.elv ); mCbAll = (CheckBox) findViewById( R.id.cbAll ); mTvMoney = (TextView) findViewById( R.id.tvMoney ); mTvTotal = (TextView) findViewById( R.id.tvTotal ); mCbAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (adapter != null) { adapter.changAllState(mCbAll.isChecked()); } } }); } }
base文件夹下BaseActivity
import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; import com.bwie.test.inter.IBase; import com.bwie.test.utils.SharedPreferencesUtils; import javax.inject.Inject; public abstract class BaseActivity <T extends BaseContract.BasePresenter> extends AppCompatActivity implements IBase, BaseContract.BaseView{ @Inject protected T mPresenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate( savedInstanceState ); setContentView(getContentLayout()); inject(); //绑定 if (mPresenter != null) { mPresenter.attchView(this); } } @Override public void initView(View view) { } @Override protected void onDestroy() { super.onDestroy(); //解绑 if (mPresenter != null) { mPresenter.detachView(); } } @Override public void showLoading() { } @Override public void dismissLoading() { } protected String getUid() { return (String) SharedPreferencesUtils.getParam(this, "uid", "11433"); } protected String getToken() { return (String) SharedPreferencesUtils.getParam(this, "token", "1DF7F322530946EFC7359DCE1394DD5A"); } protected void toast(String str){ Toast.makeText(this,str,Toast.LENGTH_SHORT).show(); } }
BaseContract
public class BaseContract { //抽取所有Presenter共性,比如绑定,解绑 public interface BasePresenter<T extends BaseView> { void attchView(T view); void detachView(); } //抽取所有View的共性,比如显示进度条和关闭进度 public interface BaseView { void showLoading(); void dismissLoading(); } }
BasePresenter
public class BasePresenter<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> { protected T mView; @Override public void attchView(T view) { this.mView = view; } @Override public void detachView() { if (mView != null) { mView = null; } } }
contract文件夹下ShopcartContract
import com.bwie.test.bean.GetCartsBean; import com.bwie.test.bean.SellerBean; import com.bwie.test.shoppingcart.base.BaseContract; import java.util.List; public class ShopcartContract { public interface View extends BaseContract.BaseView { void showCartList(List<SellerBean> groupList, List<List<GetCartsBean.DataBean.ListBean>> childList); void updateCartsSuccess(String msg); void deleteCartSuccess(String msg); } public interface Presenter extends BaseContract.BasePresenter<View> { void getCarts(String uid, String token); void updateCarts(String uid, String sellerid, String pid, String num, String selected, String token); void deleteCart(String uid, String pid, String token); } }
presenter文件夹下ShopcartPresenter
import android.annotation.SuppressLint; import com.bwie.test.bean.BaseBean; import com.bwie.test.bean.GetCartsBean; import com.bwie.test.bean.SellerBean; import com.bwie.test.net.DeleteCartApi; import com.bwie.test.net.GetCartApi; import com.bwie.test.net.UpdateCartApi; import com.bwie.test.shoppingcart.base.BasePresenter; import com.bwie.test.shoppingcart.contract.ShopcartContract; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.functions.Consumer; import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; public class ShopcartPresenter extends BasePresenter<ShopcartContract.View> implements ShopcartContract.Presenter{ private GetCartApi getCartApi; private UpdateCartApi updateCartApi; private DeleteCartApi deleteCartApi; @Inject public ShopcartPresenter(GetCartApi getCartApi, UpdateCartApi updateCartApi, DeleteCartApi deleteCartApi) { this.getCartApi = getCartApi; this.updateCartApi = updateCartApi; this.deleteCartApi = deleteCartApi; } @Override public void getCarts(String uid, String token) { getCartApi.getCatagory( uid,token ) .subscribeOn( Schedulers.io()) .observeOn( AndroidSchedulers.mainThread()) .subscribe( new Consumer<GetCartsBean>() { @Override public void accept(GetCartsBean getCartsBean) throws Exception { //用于封装一级列表 List<SellerBean> groupList = new ArrayList<>(); // 用于封装二级列表 List<List<GetCartsBean.DataBean.ListBean>> childList = new ArrayList<>(); List<GetCartsBean.DataBean> data = getCartsBean.getData(); if(data==null){ return; } for (int i=0;i<data.size();i++) { GetCartsBean.DataBean dataBean = data.get( i ); SellerBean sellerBean = new SellerBean(); sellerBean.setSellerName( dataBean.getSellerName() ); sellerBean.setSellerid(dataBean.getSellerid()); sellerBean.setSelected(isSellerProductAllSelect(dataBean)); //true或者false要根据该商家下面的商品是否全选 groupList.add(sellerBean); List<GetCartsBean.DataBean.ListBean> list = dataBean.getList(); childList.add(list); } if (mView != null) { mView.showCartList(groupList, childList); } } } ); } @Override public void updateCarts(String uid, String sellerid, String pid, String num, String selected, String token) { updateCartApi.updateCarts(uid, sellerid, pid, num, selected, token) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(new Function<BaseBean, String>() { @Override public String apply(BaseBean baseBean) throws Exception { return baseBean.getMsg(); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { if (mView != null) { mView.updateCartsSuccess(s); } } }); } @Override public void deleteCart(String uid, String pid, String token) { deleteCartApi.deleteCart(uid, pid, token) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(new Function<BaseBean, String>() { @Override public String apply(BaseBean baseBean) throws Exception { return baseBean.getMsg(); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { if (mView != null) { mView.updateCartsSuccess(s); } } }); } /** * 判断该商家下面的商品是否全选 * @return */ private boolean isSellerProductAllSelect(GetCartsBean.DataBean dataBean) { //获取该商家下面的所有商品 List<GetCartsBean.DataBean.ListBean> list = dataBean.getList(); for (int i = 0; i < list.size(); i++) { GetCartsBean.DataBean.ListBean listBean = list.get(i); if (0 == listBean.getSelected()) { //如果是0的话,表示有一个商品未选中 return false; } } return true; } }
app文件夹下MyApp
import android.app.Application; import com.facebook.drawee.backends.pipeline.Fresco; public class MyApp extends Application{ @Override public void onCreate() { super.onCreate(); //初始化 Fresco.initialize(this); } }
adapter文件夹下ShopcartAdapter
import android.app.ProgressDialog; import android.content.Context; import android.view.LayoutInflater; 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.bumptech.glide.Glide; import com.bwie.test.shoppingcart.R; import com.bwie.test.bean.GetCartsBean; import com.bwie.test.bean.SellerBean; import com.bwie.test.shoppingcart.presenter.ShopcartPresenter; import com.bwie.test.utils.AddSubView; import com.bwie.test.utils.SharedPreferencesUtils; import java.util.List; public class ShopcartAdapter extends BaseExpandableListAdapter{ private Context context; private List<SellerBean> groupList; private List<List<GetCartsBean.DataBean.ListBean>> childList; private LayoutInflater inflater; private ProgressDialog progressDialog; private ShopcartPresenter shopcartPresenter; private final String uid; private final String token; private static final int CLICK_PRODUCT = 0; private static final int CLICK_SELLER = 1; private static final int CLICK_ALL = 2; private static int state = 0; private int cIndex = 0;//商家下商品的下标 private int gIndex = 0;//点击的商家下标 private int selected;//点击商家的时候,该商家的checkbox选中状态 public ShopcartAdapter(Context context, List<SellerBean> groupList, List<List<GetCartsBean.DataBean .ListBean>> childList, ProgressDialog progressDialog, ShopcartPresenter shopcartPresenter) { this.context = context; this.groupList = groupList; this.childList = childList; this.progressDialog = progressDialog; this.shopcartPresenter = shopcartPresenter; inflater = LayoutInflater.from(context); uid = (String) SharedPreferencesUtils.getParam(context, "uid", "11433"); token = (String) SharedPreferencesUtils.getParam(context, "token", " 1DF7F322530946EFC7359DCE1394DD5A"); } @Override public int getGroupCount() { return groupList.size(); } @Override public int getChildrenCount(int groupPosition) { return childList.get(groupPosition).size(); } @Override public Object getGroup(int groupPosition) { return groupList.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return childList.get(groupPosition).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 true; } @Override public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { final GroupViewHolder groupViewHolder; if (convertView == null) { groupViewHolder = new GroupViewHolder(); convertView = inflater.inflate(R.layout.shopcart_seller_item, null); groupViewHolder.cbSeller = convertView.findViewById(R.id.cbSeller); groupViewHolder.tvSeller = convertView.findViewById(R.id.tvSeller); convertView.setTag(groupViewHolder); } else { groupViewHolder = (GroupViewHolder) convertView.getTag(); } final SellerBean sellerBean = groupList.get(groupPosition); groupViewHolder.cbSeller.setChecked(sellerBean.isSelected()); groupViewHolder.tvSeller.setText(sellerBean.getSellerName()); //给商家的checkbox设置点击事件 groupViewHolder.cbSeller.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { state = CLICK_SELLER; gIndex = groupPosition; //显示进度条 progressDialog.show(); GetCartsBean.DataBean.ListBean listBean = childList.get(groupPosition).get(cIndex); int pid = listBean.getPid(); int num = listBean.getNum(); selected = groupViewHolder.cbSeller.isChecked() ? 1 : 0; shopcartPresenter.updateCarts(uid, sellerBean.getSellerid() + "", pid + "", num + "", selected + "", token); } }); return convertView; } @Override public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { final ChildViewHolder childViewHolder; if (convertView == null) { childViewHolder = new ChildViewHolder(); convertView = inflater.inflate(R.layout.shopcart_seller_product_item, null); childViewHolder.cbProduct = convertView.findViewById(R.id.cbProduct); childViewHolder.iv = convertView.findViewById(R.id.iv); childViewHolder.tvTitle = convertView.findViewById(R.id.tvTitle); childViewHolder.tvPrice = convertView.findViewById(R.id.tvPrice); childViewHolder.tvDel = convertView.findViewById(R.id.tvDel); childViewHolder.addSubView = convertView.findViewById(R.id.addSubCard); convertView.setTag(childViewHolder); } else { childViewHolder = (ChildViewHolder) convertView.getTag(); } final GetCartsBean.DataBean.ListBean listBean = childList.get(groupPosition).get(childPosition); childViewHolder.cbProduct.setChecked(listBean.getSelected() == 1 ? true : false); childViewHolder.tvTitle.setText(listBean.getTitle()); childViewHolder.tvPrice.setText(listBean.getPrice() + ""); Glide.with(context).load(listBean.getImages().split("\\|")[0]).into(childViewHolder.iv); childViewHolder.addSubView.setNum(listBean.getNum() + ""); //给二级列表的checkbox设置点击事件 childViewHolder.cbProduct.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { state = CLICK_PRODUCT; //更新购物车 SellerBean sellerBean = groupList.get(groupPosition); String sellerid = sellerBean.getSellerid(); int pid = listBean.getPid(); int num = listBean.getNum(); int selected = childViewHolder.cbProduct.isChecked() ? 1 : 0; progressDialog.show(); shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", selected + "", token); } }); //给减号设置点击事件 childViewHolder.addSubView.setSubOnclickListener(new View.OnClickListener() { @Override public void onClick(View v) { state = CLICK_PRODUCT; //先获取原先的数量 int num = listBean.getNum(); if (num == 1) { Toast.makeText(context, "数量不能小于1", Toast.LENGTH_SHORT).show(); return; } num--; //去更新购物车 SellerBean sellerBean = groupList.get(groupPosition); String sellerid = sellerBean.getSellerid(); int pid = listBean.getPid(); int selected = childViewHolder.cbProduct.isChecked() ? 1 : 0; progressDialog.show(); shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", selected + "", token); } }); //给加号设置点击事件 childViewHolder.addSubView.setAddOnclickListener(new View.OnClickListener() { @Override public void onClick(View v) { state = CLICK_PRODUCT; //先获取原先的数量 int num = listBean.getNum(); num++; //去更新购物车 SellerBean sellerBean = groupList.get(groupPosition); String sellerid = sellerBean.getSellerid(); int pid = listBean.getPid(); int selected = childViewHolder.cbProduct.isChecked() ? 1 : 0; progressDialog.show(); shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", selected + "", token); } }); //给删除设置点击事件 childViewHolder.tvDel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { state = CLICK_PRODUCT; //去删除购物车 int pid = listBean.getPid(); shopcartPresenter.deleteCart(uid, pid + "", token); } }); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } class GroupViewHolder { CheckBox cbSeller; TextView tvSeller; } class ChildViewHolder { CheckBox cbProduct; ImageView iv; TextView tvTitle; TextView tvPrice; TextView tvDel; AddSubView addSubView; } //删除成功回调接口 public void delSuccess() { shopcartPresenter.getCarts(uid, token); } /** * 更新购物车成功后走的方法 */ public void updateSuceess() { progressDialog.dismiss(); if (state == CLICK_PRODUCT) { shopcartPresenter.getCarts(uid, token); } else if (state == CLICK_SELLER) { //判断该商家下是否还有别的商品,如果有则继续更新 cIndex++; //获取该商家下的商品列表个数 int pCount = childList.get(gIndex).size(); if (cIndex >= pCount) { //该商家下的商品已经遍历完成 cIndex = 0; shopcartPresenter.getCarts(uid, token); } else { //接着更新该商家下的其它商品 SellerBean sellerBean = groupList.get(gIndex); String sellerid = sellerBean.getSellerid(); GetCartsBean.DataBean.ListBean listBean = childList.get(gIndex).get(cIndex); int pid = listBean.getPid(); int num = listBean.getNum(); shopcartPresenter.updateCarts(uid, sellerid + "", pid + "", num + "", selected + "", token); } } else if (state == CLICK_ALL) { //先更新该商家下的商品 cIndex++; if (cIndex >= childList.get(gIndex).size()) { //该商家下的商品已经更新完成 cIndex = 0; gIndex++; if (gIndex >= groupList.size()) { //所有商家都已更新完成 //重新获取购物车列表 shopcartPresenter.getCarts(uid, token); return; } //接着更新该商家下的其它商品 SellerBean sellerBean = groupList.get(gIndex); String sellerid = sellerBean.getSellerid(); GetCartsBean.DataBean.ListBean listBean = childList.get(gIndex).get(cIndex); int pid = listBean.getPid(); int num = listBean.getNum(); shopcartPresenter.updateCarts(uid, sellerid + "", pid + "", num + "", selected + "", token); } else { //接着更新该商家下的其它商品 SellerBean sellerBean = groupList.get(gIndex); String sellerid = sellerBean.getSellerid(); GetCartsBean.DataBean.ListBean listBean = childList.get(gIndex).get(cIndex); int pid = listBean.getPid(); int num = listBean.getNum(); shopcartPresenter.updateCarts(uid, sellerid + "", pid + "", num + "", selected + "", token); } } } /** * 遍历所有商家,判断是否都选中 * @return */ public boolean isAllSelected() { for (int i = 0; i < groupList.size(); i++) { if (!groupList.get(i).isSelected()) { return false; } } return true; } public void changAllState(boolean bool) { progressDialog.show(); state = CLICK_ALL; gIndex = 0; cIndex = 0; selected = bool ? 1 : 0; SellerBean sellerBean = groupList.get(gIndex); String sellerid = sellerBean.getSellerid(); GetCartsBean.DataBean.ListBean listBean = childList.get(gIndex).get(cIndex); int pid = listBean.getPid(); int num = listBean.getNum(); shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", selected + "", token); } public String[] getMoneyAndCount() { double money = 0; int count = 0; for (int i = 0; i < groupList.size(); i++) { for (int j = 0; j < childList.get(i).size(); j++) { GetCartsBean.DataBean.ListBean listBean = childList.get(i).get(j); if (listBean.getSelected() == 1) { count += listBean.getNum(); money += listBean.getPrice() * listBean.getNum(); } } } return new String[]{money + "", count + ""}; } }
component文件夹下HttpComponent
import com.bwie.test.module.HttpModule; import com.bwie.test.shoppingcart.ShoppingCartActivity; import dagger.Component; @Component(modules = HttpModule.class) public interface HttpComponent { void inject(ShoppingCartActivity shoppingCartActivity); }
inter文件夹下IBase
import android.view.View; public interface IBase { int getContentLayout(); void inject(); void initView(View view); }
OnItemClickListener
public interface OnItemClickListener { void onItemClick(int position); void onLongItemClick(int position); }
module文件夹下HttpModule
import com.bwie.test.net.AddCartApi; import com.bwie.test.net.AddCartApiService; import com.bwie.test.net.Api; import com.bwie.test.net.CreateOrderApi; import com.bwie.test.net.CreateOrderApiService; import com.bwie.test.net.DeleteCartApi; import com.bwie.test.net.DeleteCartApiService; import com.bwie.test.net.GetCartApi; import com.bwie.test.net.GetCartApiService; import com.bwie.test.net.UpdateCartApi; import com.bwie.test.net.UpdateCartApiService; import com.bwie.test.utils.MyInterceptor; import java.util.concurrent.TimeUnit; import dagger.Module; import dagger.Provides; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; @Module public class HttpModule { @Provides OkHttpClient.Builder provideOkHttpClientBuilder() { HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); return new OkHttpClient.Builder() .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .addInterceptor(httpLoggingInterceptor) .connectTimeout(10, TimeUnit.SECONDS); } @Provides Retrofit.Builder provideRetrofit(OkHttpClient.Builder builder){ builder.addInterceptor(new MyInterceptor()); return new Retrofit.Builder() .baseUrl( Api.BASEURL) .addCallAdapterFactory( RxJava2CallAdapterFactory.create()) .addConverterFactory( GsonConverterFactory.create()) .client(builder.build()); } @Provides AddCartApi provideAddCartApi(Retrofit.Builder builder) { Retrofit retrofit = builder.build(); AddCartApiService addCartApiService = retrofit.create(AddCartApiService.class); return AddCartApi.getAddCartApi(addCartApiService); } @Provides GetCartApi provideGetCartApi(Retrofit.Builder builder) { Retrofit retrofit = builder.build(); GetCartApiService getCartApiService = retrofit.create(GetCartApiService.class); return GetCartApi.getGetCartApi(getCartApiService); } @Provides UpdateCartApi provideUpdateCartApi(Retrofit.Builder builder) { Retrofit retrofit = builder.build(); UpdateCartApiService updateCartApiService = retrofit.create(UpdateCartApiService.class); return UpdateCartApi.getUpdateCartApi(updateCartApiService); } @Provides DeleteCartApi provideDeleteCartApi(Retrofit.Builder builder) { Retrofit retrofit = builder.build(); DeleteCartApiService deleteCartApiService = retrofit.create(DeleteCartApiService.class); return DeleteCartApi.getDeleteCartApi(deleteCartApiService); } @Provides CreateOrderApi provideCreateOrderApi(Retrofit.Builder builder) { Retrofit retrofit = builder.build(); CreateOrderApiService createOrderApiService = retrofit.create( CreateOrderApiService.class ); return CreateOrderApi.getCreateOrderApi( createOrderApiService ); } }
net文件夹下Api
public interface Api { String BASEURL = "https://www.zhaoapi.cn/"; }
AddCartApi
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; public class AddCartApi { private static AddCartApi addCartApi; private AddCartApiService addCartApiService; private AddCartApi(AddCartApiService addCartApiService) { this.addCartApiService = addCartApiService; } public static AddCartApi getAddCartApi(AddCartApiService addCartApiService) { if (addCartApi == null) { addCartApi = new AddCartApi(addCartApiService); } return addCartApi; } public Observable<BaseBean> getCatagory(String uid, String pid, String token) { return addCartApiService.addCart(uid, pid, token); } }
AddCartApiService
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface AddCartApiService { @FormUrlEncoded @POST("product/addCart") Observable<BaseBean> addCart(@Field("Uid") String uid, @Field("Pid") String pid, @Field("Token") String token); }
CreateOrderApi
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; public class CreateOrderApi { private static CreateOrderApi createOrderApi; private CreateOrderApiService createOrderApiService; private CreateOrderApi(CreateOrderApiService createOrderApiService) { this.createOrderApiService = createOrderApiService; } public static CreateOrderApi getCreateOrderApi(CreateOrderApiService createOrderApiService) { if (createOrderApi == null) { createOrderApi = new CreateOrderApi(createOrderApiService); } return createOrderApi; } public Observable<BaseBean> getCatagory(String uid, String price, String token) { return createOrderApiService.createOrder(uid, price, token); } }
CreateOrderApiService
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface CreateOrderApiService { @FormUrlEncoded @POST("product/createOrder") Observable<BaseBean> createOrder(@Field("Uid") String uid, @Field("Price") String price, @Field("Token") String token); }
DeleteCartApi
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; public class DeleteCartApi { private static DeleteCartApi deleteCartApi; private DeleteCartApiService deleteCartApiService; private DeleteCartApi(DeleteCartApiService deleteCartApiService) { this.deleteCartApiService = deleteCartApiService; } public static DeleteCartApi getDeleteCartApi(DeleteCartApiService deleteCartApiService) { if (deleteCartApi == null) { deleteCartApi = new DeleteCartApi(deleteCartApiService); } return deleteCartApi; } public Observable<BaseBean> deleteCart(String uid, String pid, String token) { return deleteCartApiService.deleteCart(uid, pid, token); } }
DeleteCartApiService
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface DeleteCartApiService { @FormUrlEncoded @POST("product/deleteCart") Observable<BaseBean> deleteCart(@Field("uid") String uid, @Field("pid") String pid, @Field("token") String token); }
GetCartApi
import com.bwie.test.bean.GetCartsBean; import io.reactivex.Observable; public class GetCartApi { private static GetCartApi getCartApi; private GetCartApiService getCartApiService; private GetCartApi(GetCartApiService getCartApiService) { this.getCartApiService = getCartApiService; } public static GetCartApi getGetCartApi(GetCartApiService getCartApiService) { if (getCartApi == null) { getCartApi = new GetCartApi(getCartApiService); } return getCartApi; } public Observable<GetCartsBean> getCatagory(String uid, String token) { return getCartApiService.getCart(uid, token); } }
GetCartApiService
import com.bwie.test.bean.GetCartsBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface GetCartApiService { @FormUrlEncoded @POST("product/getCarts") Observable<GetCartsBean> getCart(@Field("Uid") String uid, @Field("Token") String token); }
UpdateCartApi
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; public class UpdateCartApi { private static UpdateCartApi updateCartApi; private UpdateCartApiService updateCartApiService; private UpdateCartApi(UpdateCartApiService updateCartApiService) { this.updateCartApiService = updateCartApiService; } public static UpdateCartApi getUpdateCartApi(UpdateCartApiService updateCartApiService) { if (updateCartApi == null) { updateCartApi = new UpdateCartApi(updateCartApiService); } return updateCartApi; } public Observable<BaseBean> updateCarts(String uid, String sellerid, String pid, String num, String selected, String token) { return updateCartApiService.updateCarts(uid, sellerid, pid, num, selected, token); } }
UpdateCartApiService
import com.bwie.test.bean.BaseBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface UpdateCartApiService { @FormUrlEncoded @POST("product/updateCarts") Observable<BaseBean> updateCarts(@Field("uid") String uid, @Field("sellerid") String sellerid, @Field("pid") String pid, @Field("num") String num, @Field("selected") String selected, @Field("token") String token); }
utils文件夹下AddSubView
import android.content.Context; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.bwie.test.shoppingcart.R; public class AddSubView extends LinearLayout { private TextView sub; private TextView num; private TextView add; public AddSubView(Context context) { this(context, null); } public AddSubView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); View view = LayoutInflater.from(context).inflate(R.layout.add_sub_view, this); sub = findViewById(R.id.child_text_jian); num = findViewById(R.id.child_text_num); add = findViewById(R.id.child_text_add); } /** * 设置数量 * @param str */ public void setNum(String str) { num.setText(str); } /** * 获取数量 * @return */ public String getNum() { return num.getText().toString(); } /** * 给加号设置点击事件 * @param onclickListener */ public void setAddOnclickListener(OnClickListener onclickListener) { add.setOnClickListener(onclickListener); } /** * 给减号设置点击事件 * @param onclickListener */ public void setSubOnclickListener(OnClickListener onclickListener) { sub.setOnClickListener(onclickListener); } }
DialogUtil
import android.app.ProgressDialog; import android.content.Context; public class DialogUtil { public static ProgressDialog getProgressDialog(Context context) { ProgressDialog progressDialog = new ProgressDialog(context); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setMessage("正在加载..."); progressDialog.setCancelable(false); return progressDialog; } }
GlideImageLoader
import android.content.Context; import android.widget.ImageView; import com.bumptech.glide.Glide; import com.youth.banner.loader.ImageLoader; public class GlideImageLoader extends ImageLoader { @Override public void displayImage(Context context, Object path, ImageView imageView) { imageView.setScaleType(ImageView.ScaleType.FIT_XY); //Glide 加载图片简单用法 Glide.with(context).load(path).into(imageView); } }
MyInterceptor
import java.io.IOException; import okhttp3.FormBody; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; import okhttp3.logging.HttpLoggingInterceptor; public class MyInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Response response; //区分是GET请求还是POST请求 Request originRequest = chain.request(); if ("GET".equals(originRequest.method())) { HttpUrl httpUrl = originRequest.url() .newBuilder() .addQueryParameter("source", "android") .addQueryParameter("appVersion","101") .build(); Request request = new Request.Builder().url(httpUrl).build(); //发送请求 response = chain.proceed(request); } else { FormBody.Builder builder = new FormBody.Builder(); FormBody body = (FormBody) originRequest.body(); int size = body.size(); for (int i = 0; i < size; i++) { builder.add(body.name(i), body.value(i)); } builder.add("source", "android"); builder.add("appVersion","101"); FormBody formBody = builder.build(); Request request = new Request.Builder() .url(originRequest.url()) .post(formBody) .build(); response = chain.proceed(request); } return response; } }
SharedPreferencesUtils
package com.bwie.test.utils; import android.content.Context; import android.content.SharedPreferences; public class SharedPreferencesUtils { /** * 保存在手机里面的文件名 */ private static final String FILE_NAME = "share_date"; /** * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 * @param context * @param key * @param object */ public static void setParam(Context context , String key, Object object){ String type = object.getClass().getSimpleName(); SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); if("String".equals(type)){ editor.putString(key, (String)object); } else if("Integer".equals(type)){ editor.putInt(key, (Integer)object); } else if("Boolean".equals(type)){ editor.putBoolean(key, (Boolean)object); } else if("Float".equals(type)){ editor.putFloat(key, (Float)object); } else if("Long".equals(type)){ editor.putLong(key, (Long)object); } editor.commit(); } /** * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 * @param context * @param key * @param defaultObject * @return */ public static Object getParam(Context context , String key, Object defaultObject){ String type = defaultObject.getClass().getSimpleName(); SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); if("String".equals(type)){ return sp.getString(key, (String)defaultObject); } else if("Integer".equals(type)){ return sp.getInt(key, (Integer)defaultObject); } else if("Boolean".equals(type)){ return sp.getBoolean(key, (Boolean)defaultObject); } else if("Float".equals(type)){ return sp.getFloat(key, (Float)defaultObject); } else if("Long".equals(type)){ return sp.getLong(key, (Long)defaultObject); } return null; } }
bean文件夹下BaseBean
public class BaseBean { private String msg; private String code; 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; } }
GetCartsBean
import java.util.List; public class GetCartsBean { private String msg; private String code; private List<DataBean> 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 List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { private String sellerName; private String sellerid; private List<ListBean> list; 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 { 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 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; } } } }
SellerBean
import java.io.Serializable; public class SellerBean implements Serializable{ private String sellerName; private String sellerid; private boolean selected;//商家是否选中 public boolean isSelected() { return selected; } public void setSelected(boolean selected) { this.selected = selected; } 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; } }