apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
defaultConfig {
applicationId rootProject.ext.android.applicationId
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
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 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"]
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'
implementation 'com.sunfusheng:marqueeview:1.3.3'
implementation 'com.jcodecraeer:xrecyclerview:1.3.2'
implementation 'com.youth.banner:banner:1.4.10'
implementation 'com.android.support:design:27.1.1'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
implementation 'com.github.bumptech.glide:glide:4.7.1'
implementation 'com.amap.api:map2d:latest.integration'
implementation 'com.amap.api:location:latest.integration'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
}
ext {
android = [
compileSdkVersion: 27,
applicationId : "com.example.app.component",//改为自己的包名
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"
]
}
android:name=".app.MyApp" -------------------------------------------------------------------------------------------------------------------------- 布局文件 activity_main.xml
add_sub_view.xml -------------------------------------------------------------------------------------------------------------------------- BaseBean GetCartsBean SellerBean -------------------------------------------------------------------------------------------------------------------------- Api DeleteCartApi DeleteCartApiService GetCartApi GetCartApiService UpdateCartApi UpdateCartApiService MyInterceptor -------------------------------------------------------------------------------------------------------------------------- Base包 IBase
BaseContract
BasePresenter
BaseActivity
-------------------------------------------------------------------------------------------------------------------------- AddSubView DialogUtil SharedPreferencesUtils -------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------- ShopcartContract -------------------------------------------------------------------------------------------------------------------------- ShopcartPresenter HttpModule清单文件注册
MyApp
import android.app.Application;
import com.facebook.drawee.backends.pipeline.Fresco;
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化Fresco
Fresco.initialize(this);
}
}
drawable.cart_biankuang.xml
android:color="#000000" /><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=".MainActivity">
<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>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
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="8dp"
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="8dp"
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="8dp">TextView>
LinearLayout>
shopcart_seller_item.xml
<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
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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.example.zhouliulianxi.utils.AddSubView
android:id="@+id/addSubCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true">com.example.zhouliulianxi.utils.AddSubView>
RelativeLayout>
LinearLayout>
LinearLayout>
RelativeLayout>
Bean包
public class BaseBean {
/**
* msg : 加购成功
* code : 0
*/
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;
}
}
public class GetCartsBean {
/**
* msg : 请求成功
* code : 0
* data : [{"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":2,"pid":46,"price":234,
* "pscid":39,"selected":1,"sellerid":2,"subhead":"【iPhone新品上市】新一代iPhone,让智能看起来更不一样","title":"Apple iPhone 8 Plus
* (A1864) 64GB 金色 移动联通电信4G手机"},{"bargainPrice":11800,"createtime":"2017-10-14T21:38:26",
* "detailUrl":"https://item.m.jd.com/product/5025518.html?utm#_source=androidapp&utm#_medium=appshare&utm
* #_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg
* .com/n0/jfs/t8830/106/1760940277/195595/5cf9412f/59bf2ef5N5ab7dc16.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t5428/70/1520969931/274676/b644dd0d/591128e7Nd2f70da0.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t5566/365/1519564203/36911/620c750c/591128eaN54ac3363.jpg!q70.jpg","num":7,"pid":58,"price":6399,
* "pscid":40,"selected":1,"sellerid":2,"subhead":"升级4G大显存!Nvme协议Pcie SSD,速度快人一步】GTX1050Ti就选拯救者!专业游戏键盘&新模具全新设计!",
* "title":"联想(Lenovo)拯救者R720 15.6英寸游戏笔记本电脑(i5-7300HQ 8G 1T+128G SSD GTX1050Ti 4G IPS 黑)"}],"sellerName":"商家2",
* "sellerid":"2"},{"list":[{"bargainPrice":22.9,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m
* .jd.com/product/2542855.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term
* =QQfriends","images":"https://m.360buyimg
* .com/n0/jfs/t1930/284/2865629620/390243/e3ade9c4/56f0a08fNbd3a1235.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t2137/336/2802996626/155915/e5e90d7a/56f0a09cN33e01bd0.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t1882/31/2772215910/389956/c8dbf370/56f0a0a2Na0c86ea6.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t2620/166/2703833710/312660/531aa913/57709035N33857877.jpg!q70.jpg","num":1,"pid":26,"price":88,
* "pscid":2,"selected":1,"sellerid":3,"subhead":"三只松鼠零食特惠,专区满99减50,满199减100,火速抢购》","title":"三只松鼠 坚果炒货 零食奶油味
* 碧根果225g/袋"}],"sellerName":"商家3","sellerid":"3"},{"list":[{"bargainPrice":22.9,
* "createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd
* .com/product/2542855.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term
* =QQfriends","images":"https://m.360buyimg
* .com/n0/jfs/t1930/284/2865629620/390243/e3ade9c4/56f0a08fNbd3a1235.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t2137/336/2802996626/155915/e5e90d7a/56f0a09cN33e01bd0.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t1882/31/2772215910/389956/c8dbf370/56f0a0a2Na0c86ea6.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t2620/166/2703833710/312660/531aa913/57709035N33857877.jpg!q70.jpg","num":2,"pid":27,"price":488,
* "pscid":2,"selected":1,"sellerid":4,"subhead":"三只松鼠零食特惠,专区满99减50,满199减100,火速抢购》","title":"三只松鼠 坚果炒货 零食奶油味
* 碧根果225g/袋"},{"bargainPrice":11800,"createtime":"2017-10-14T21:48:08","detailUrl":"https://mitem.jd
* .hk/ware/view.action?wareId=1988853309&cachekey=1acb07a701ece8d2434a6ae7fa6870a1",
* "images":"https://m.360buyimg.com/n0/jfs/t6130/97/1370670410/180682/1109582a/593276b1Nd81fe723.jpg!q70.jpg
* |https://m.360buyimg.com/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f
* .jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f
* .jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5815/178/2614671118/51656/7f52d137/593276c7N107b725a
* .jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5878/60/2557817477/30873/4502b606/593276caN5a7d6357.jpg!q70.jpg",
* "num":2,"pid":60,"price":13888,"pscid":40,"selected":1,"sellerid":4,"subhead":"购买电脑办公部分商品满1元返火车票5元优惠券(返完即止)",
* "title":"全球购 新款Apple MacBook Pro 苹果笔记本电脑 银色VP2新13英寸Bar i5/8G/256G"}],"sellerName":"商家4","sellerid":"4"},
* {"list":[{"bargainPrice":22.9,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd
* .com/product/2542855.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term
* =QQfriends","images":"https://m.360buyimg
* .com/n0/jfs/t1930/284/2865629620/390243/e3ade9c4/56f0a08fNbd3a1235.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t2137/336/2802996626/155915/e5e90d7a/56f0a09cN33e01bd0.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t1882/31/2772215910/389956/c8dbf370/56f0a0a2Na0c86ea6.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t2620/166/2703833710/312660/531aa913/57709035N33857877.jpg!q70.jpg","num":1,"pid":31,"price":788,
* "pscid":2,"selected":1,"sellerid":8,"subhead":"三只松鼠零食特惠,专区满99减50,满199减100,火速抢购》","title":"三只松鼠 坚果炒货 零食奶油味
* 碧根果225g/袋"},{"bargainPrice":3455,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd
* .com/product/12224420750.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term
* =QQfriends","images":"https://m.360buyimg
* .com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t8803/356/1478945529/489755/2a163ace/59ba5e84N7bb9a666.jpg!q70.jpg","num":1,"pid":52,"price":666,
* "pscid":39,"selected":1,"sellerid":8,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机
* 黑色 全网通 (6GB+64GB)【标配版】"}],"sellerName":"商家8","sellerid":"8"},{"list":[{"bargainPrice":11800,
* "createtime":"2017-10-03T23:53:28","detailUrl":"https://mitem.jd.hk/ware/view
* .action?wareId=1988853309&cachekey=1acb07a701ece8d2434a6ae7fa6870a1","images":"https://m.360buyimg
* .com/n0/jfs/t6130/97/1370670410/180682/1109582a/593276b1Nd81fe723.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t5815/178/2614671118/51656/7f52d137/593276c7N107b725a.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t5878/60/2557817477/30873/4502b606/593276caN5a7d6357.jpg!q70.jpg","num":1,"pid":67,"price":14000,
* "pscid":40,"selected":1,"sellerid":11,"subhead":"购买电脑办公部分商品满1元返火车票5元优惠券(返完即止)","title":"全球购 新款Apple MacBook
* Pro 苹果笔记本电脑 银色VP2新13英寸Bar i5/8G/256G"}],"sellerName":"商家11","sellerid":"11"},{"list":[{"bargainPrice":111.99,
* "createtime":"2017-10-14T21:39:05","detailUrl":"https://item.m.jd
* .com/product/4719303.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term
* =QQfriends","images":"https://m.360buyimg
* .com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1N9a2b1532.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1N7f2adb87.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbNd989ba0a.jpg!q70.jpg","num":1,"pid":20,"price":599,
* "pscid":1,"selected":1,"sellerid":13,
* .com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1N9a2b1532.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1N7f2adb87.jpg!q70.jpg|https://m.360buyimg
* .com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbNd989ba0a.jpg!q70.jpg","num":2,"pid":6,"price":7.99,
* "pscid":1,"selected":1,"sellerid":22,r i5/8G/256G"}],"sellerName":"商家22","sellerid":"22"}]
*/
private String msg;
private String code;
private List
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;
}
}
net包
public interface Api {
String BASEURL = "https://www.zhaoapi.cn/";
}
import com.example.zhouliulianxi.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
import com.example.zhouliulianxi.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
import com.example.zhouliulianxi.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
import com.example.zhouliulianxi.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
import com.example.zhouliulianxi.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
import com.example.zhouliulianxi.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
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class MyInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
//创建一个FormBody.Builder对象,用于添加公共参数
FormBody.Builder builder = new FormBody.Builder();
//先获取原始的请求
Request originalRequest = chain.request();
//获取原始请求里的请求体数据
FormBody formBody = (FormBody) originalRequest.body();
for (int i = 0; i < formBody.size(); i++) {
//先把原始的请求体的参数添加到builder里
builder.add(formBody.name(i),formBody.value(i));
}
//添加公共参数
builder.add("source","android");
FormBody body = builder.build();
//创建一个新的Request
Request request = new Request.Builder()
.url(originalRequest.url())
.post(body)
.build();
Response response = chain.proceed(request);
return response;
}
}
import android.view.View;
public interface IBase {
int getContentLayout();
void inject();
void initView(View view);
}
public interface BaseContract {
//抽取所有Presenter共性,比如绑定,解绑
interface BasePresenter<T extends BaseView> {
void attchView(T view);
void detachView();
}
//抽取所有View的共性,比如显示进度条和关闭进度
interface BaseView {
void showLoading();
void dismissLoading();
}
}
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;
}
}
}
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.example.zhouliulianxi.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", "");
}
protected String getToken() {
return (String) SharedPreferencesUtils.getParam(this, "token", "");
}
protected void toast(String str){
Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
}
}
utils包
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.zhouliulianxi.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);
}
}
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;
}
}
import android.content.Context;
import android.content.SharedPreferences;
/**
* SharedPreferences的一个工具类,调用setParam就能保存String, Integer, Boolean, Float, Long类型的参数
* 同样调用getParam就能获取到保存在手机里面的数据
* @author xiaanming
*
*/
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;
}
}
import com.example.zhouliulianxi.MainActivity;
import com.example.zhouliulianxi.module.HttpModule;
import dagger.Component;
@Component(modules = HttpModule.class)
public interface HttpComponent {
void inject(MainActivity mainActivity);
}
import com.example.zhouliulianxi.base.BaseContract;
import com.example.zhouliulianxi.bean.GetCartsBean;
import com.example.zhouliulianxi.bean.SellerBean;
import java.util.List;
public interface ShopcartContract {
interface View extends BaseContract.BaseView {
void showCartList(List
> childList);
void updateCartsSuccess(String msg);
void deleteCartSuccess(String msg);
}
interface Presenter extends BaseContract.BasePresenter
shopcart包
import com.example.zhouliulianxi.base.BasePresenter;
import com.example.zhouliulianxi.bean.BaseBean;
import com.example.zhouliulianxi.bean.GetCartsBean;
import com.example.zhouliulianxi.bean.SellerBean;
import com.example.zhouliulianxi.contract.ShopcartContract;
import com.example.zhouliulianxi.net.DeleteCartApi;
import com.example.zhouliulianxi.net.GetCartApi;
import com.example.zhouliulianxi.net.UpdateCartApi;
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
> childList = new ArrayList<>();//用于封装二级列表
List
import com.example.zhouliulianxi.net.Api;
import com.example.zhouliulianxi.net.DeleteCartApi;
import com.example.zhouliulianxi.net.DeleteCartApiService;
import com.example.zhouliulianxi.net.GetCartApi;
import com.example.zhouliulianxi.net.GetCartApiService;
import com.example.zhouliulianxi.net.MyInterceptor;
import com.example.zhouliulianxi.net.UpdateCartApi;
import com.example.zhouliulianxi.net.UpdateCartApiService;
import java.util.concurrent.TimeUnit;
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
@Module
public class HttpModule {
@Provides
OkHttpClient.Builder provideOkHttpClientBuilder() {
return new OkHttpClient.Builder()
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS);
}
@Provides
GetCartApi provideGetCartApi(OkHttpClient.Builder builder) {
builder.addInterceptor(new MyInterceptor());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASEURL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(builder.build())
.build();
GetCartApiService getCartApiService = retrofit.create(GetCartApiService.class);
return GetCartApi.getGetCartApi(getCartApiService);
}
@Provides
UpdateCartApi provideUpdateCartApi(OkHttpClient.Builder builder) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASEURL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(builder.build())
.build();
UpdateCartApiService updateCartApiService = retrofit.create(UpdateCartApiService.class);
return UpdateCartApi.getUpdateCartApi(updateCartApiService);
}
@Provides
DeleteCartApi provideDeleteCartApi(OkHttpClient.Builder builder) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASEURL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(builder.build())
.build();
DeleteCartApiService deleteCartApiService = retrofit.create(DeleteCartApiService.class);
return DeleteCartApi.getDeleteCartApi(deleteCartApiService);
}
}
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.example.zhouliulianxi.R;
import com.example.zhouliulianxi.bean.GetCartsBean;
import com.example.zhouliulianxi.bean.SellerBean;
import com.example.zhouliulianxi.shopcart.ShopcartPresenter;
import com.example.zhouliulianxi.utils.AddSubView;
import com.example.zhouliulianxi.utils.SharedPreferencesUtils;
import java.util.ArrayList;
import java.util.List;
public class ElvShopcartAdapter extends BaseExpandableListAdapter {
private Context context;
private List
> childList;
private LayoutInflater inflater;
private final String uid;
private final String token;
private ProgressDialog progressDialog;
private int productIndex;
private int groupPosition;
private boolean checked;
private static final int GETCARTS = 0;//查询购物车
private static final int UPDATE_PRODUCT = 1; //更新商品
private static final int UPDATE_SELLER = 2; //更新卖家
private static int state = GETCARTS;
private boolean allSelected;
private ShopcartPresenter shopcartPresenter;
public ElvShopcartAdapter(Context context, List
>
childList, ShopcartPresenter shopcartPresenter, ProgressDialog progressDialog) {
this.context = context;
this.groupList = groupList;
this.childList = childList;
inflater = LayoutInflater.from(context);
this.shopcartPresenter = shopcartPresenter;
uid = (String) SharedPreferencesUtils.getParam(context, "uid", "13842");
token = (String) SharedPreferencesUtils.getParam(context, "token", "B418A52FCD7198F21D19CB63011CE354");
//初始化进度对话框
this.progressDialog = progressDialog;
}
@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();
}
//设置值
SellerBean sellerBean = groupList.get(groupPosition);
groupViewHolder.tvSeller.setText(sellerBean.getSellerName());
groupViewHolder.cbSeller.setChecked(sellerBean.isSelected());
//给商家checkbox设置点击事件
groupViewHolder.cbSeller.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置当前的更新状态
state = UPDATE_PRODUCT;
//显示进度条
progressDialog.show();
//默认从第一个商品开始更新购物车状态
productIndex = 0;
//全局记录一下当前更新的商家
ElvShopcartAdapter.this.groupPosition = groupPosition;
//该商家是否选中
checked = groupViewHolder.cbSeller.isChecked();
//更新商家下的商品状态
updateProductInSeller();
}
});
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);
//根据服务器返回的select值,给checkBox设置是否选中
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 = GETCARTS;
//显示进度条
progressDialog.show();
ElvShopcartAdapter.this.groupPosition = groupPosition;
//调用更新购物车接口,改变购物车的状态
//获取卖家id
String sellerid = groupList.get(groupPosition).getSellerid();
//获取pid
String pid = listBean.getPid() + "";
//是否选中
boolean childChecked = childViewHolder.cbProduct.isChecked();
shopcartPresenter.updateCarts(uid, sellerid, pid, "1", childChecked ? "1" : "0", token);
}
});
//给加号设置点击事件
childViewHolder.addSubView.setAddOnclickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.show();
state = GETCARTS;
//获取sellerId
String sellerid = groupList.get(groupPosition).getSellerid();
//获取pid
int pid = listBean.getPid();
//获取数量
int num = listBean.getNum();
num += 1;
//是否选中
String isChecked = childViewHolder.cbProduct.isChecked() ? "1" : "0";
//调用更新购物车的接口即可
shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", isChecked, token);
}
});
//给减号设置点击事件
childViewHolder.addSubView.setSubOnclickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.show();
state = GETCARTS;
//获取当前商品的数量
int num = listBean.getNum();
if (num <= 1) {
progressDialog.dismiss();
Toast.makeText(context, "数量不能小于1", Toast.LENGTH_SHORT).show();
return;
}
num -= 1;
//获取sellerId
String sellerid = groupList.get(groupPosition).getSellerid();
//获取pid
int pid = listBean.getPid();
//是否选中
String isChecked = childViewHolder.cbProduct.isChecked() ? "1" : "0";
//更新购物车
shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", isChecked, token);
}
});
//给删除设置点击事件
childViewHolder.tvDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.show();
state = GETCARTS;
//获取pid
int pid = listBean.getPid();
//删除购物车里的选项
shopcartPresenter.deleteCart(uid, pid + "", token);
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
//删除成功回调接口
public void delSuccess() {
shopcartPresenter.getCarts(uid, token);
}
class GroupViewHolder {
CheckBox cbSeller;
TextView tvSeller;
}
class ChildViewHolder {
CheckBox cbProduct;
ImageView iv;
TextView tvTitle;
TextView tvPrice;
TextView tvDel;
AddSubView addSubView;
}
//更新购物车成功回调的方法
public void updataSuccess() {
switch (state) {
case GETCARTS:
//更新成功以后调用查询购物车接口
productIndex = 0;
groupPosition = 0;
shopcartPresenter.getCarts(uid, token);
break;
case UPDATE_PRODUCT:
//更新成功一个商品以后,再接着更新该商家下面的其它商品,直到没有商品为止
productIndex++;
//下标是否越界
if (productIndex < childList.get(groupPosition).size()) {
//可以继续跟新商品
updateProductInSeller();
} else {
//商品已经全部更新完成,请查询购物车
state = GETCARTS;
updataSuccess();
}
break;
case UPDATE_SELLER:
//遍历所有商家下的商品,并更新状态
productIndex++;
//下标是否越界
if (productIndex < childList.get(groupPosition).size()) {
//可以继续跟新商品
updateProductInSeller(allSelected);
} else {
//商品已经全部更新完成,请查询购物车
productIndex = 0;
groupPosition++;
if (groupPosition < groupList.size()) {
//可以继续跟新商品
updateProductInSeller(allSelected);
} else {
//商品已经全部更新完成,请查询购物车
state = GETCARTS;
updataSuccess();
}
}
break;
}
}
private void updateProductInSeller() {
//获取SellerId
SellerBean sellerBean = groupList.get(groupPosition);
String sellerid = sellerBean.getSellerid();
//获取pid
GetCartsBean.DataBean.ListBean listBean = childList.get(groupPosition).get(productIndex);
int num = listBean.getNum();
int pid = listBean.getPid();
shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", checked ? "1" : "0", token);
}
private void updateProductInSeller(boolean bool) {
//获取SellerId
SellerBean sellerBean = groupList.get(groupPosition);
String sellerid = sellerBean.getSellerid();
//获取pid
GetCartsBean.DataBean.ListBean listBean = childList.get(groupPosition).get(productIndex);
int pid = listBean.getPid();
int num = listBean.getNum();
shopcartPresenter.updateCarts(uid, sellerid, pid + "", num + "", bool ? "1" : "0", token);
}
/**
* 计算数量和价钱
*
* @return
*/
public String[] computeMoneyAndNum() {
double sum = 0;
int num = 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) {
//该商品为选中状态
sum += listBean.getPrice() * listBean.getNum();
num += listBean.getNum();
}
}
}
return new String[]{sum + "", num + ""};
}
public void changeAllState(boolean bool) {
this.allSelected = bool;
state = UPDATE_SELLER;
//遍历商家下的商品,修改状态
updateProductInSeller(bool);
}
public List
> getchildList() {
List
> cList = new ArrayList<>();
for (int i = 0; i < groupList.size(); i++) {
List
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.example.zhouliulianxi.adapter.ElvShopcartAdapter;
import com.example.zhouliulianxi.base.BaseActivity;
import com.example.zhouliulianxi.bean.GetCartsBean;
import com.example.zhouliulianxi.bean.SellerBean;
import com.example.zhouliulianxi.component.DaggerHttpComponent;
import com.example.zhouliulianxi.contract.ShopcartContract;
import com.example.zhouliulianxi.shopcart.ShopcartPresenter;
import com.example.zhouliulianxi.utils.DialogUtil;
import java.util.List;
public class MainActivity extends BaseActivity
> childList) {
//判断所有商家是否全部选中
mCbAll.setChecked(isSellerAddSelected(groupList));
//创建适配器
adapter = new ElvShopcartAdapter(this, groupList, childList, mPresenter,
progressDialog);
mElv.setAdapter(adapter);
//获取数量和总价
String[] strings = adapter.computeMoneyAndNum();
mTvMoney.setText("总计:" + strings[0] + "元");
mTvTotal.setText("去结算("+strings[1]+"个)");
// //默认展开列表
for (int i = 0; i < groupList.size(); i++) {
mElv.expandGroup(i);
}
//关闭进度条
progressDialog.dismiss();
}
@Override
public void updateCartsSuccess(String msg) {
if (adapter!=null){
adapter.updataSuccess();
}
}
@Override
public void deleteCartSuccess(String msg) {
//调用适配器里的delSuccess()方法
if (adapter!=null){
adapter.delSuccess();
}
}
/**
* 判断所有商家是否全部选中
*
* @param groupList
* @return
*/
private boolean isSellerAddSelected(List