一,项目介绍
首先看项目流程(接口都写在model类中,不提出来一一写了)
二,项目思路分析
可以看出框架为MVP,主要思路是:1,MD5加密的登录注册。2,登陆成功后跳转到RecyclerView+网络请求(Okhttp+Retrofit+Rxjava)+Fresco显示图片实现的商品列表。3,点击列表条目跳转到详情页面。4,点击详情页面中的添加购物车,提示加购成功,点击购物车,商家和商品信息显示在购物车页面进行操作。5,购物车,使用RecyclerView实现。6,点击结算,跳转到订单页面,订单页面使用radioGroup+viewPage+Fragment。
三,项目框架预览
用到的依赖
compile 'com.facebook.fresco:fresco:0.9.0+' compile 'com.android.support:recyclerview-v7:26.1.0' compile 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' compile 'com.squareup.okhttp3:okhttp:3.9.1'//OkHttp依赖 compile 'com.android.support:recyclerview-v7:26.1.0'//RecyclerView依赖 compile 'com.liaoinstan.springview:library:1.3.0'//SpringView依赖 compile 'com.github.bumptech.glide:glide:4.3.1' //glide加载图片 compile 'com.squareup.okhttp3:logging-interceptor:3.9.0' //双击查看原图http拦截器 compile 'com.google.code.gson:gson:2.8.2' //gson依赖 compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'io.reactivex.rxjava2:rxjava:2.1.7' compile 'com.facebook.fresco:fresco:1.7.1' compile 'com.jakewharton:butterknife:8.2.1' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'com.squareup.retrofit2:converter-scalars:2.3.0' compile 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
四,首先开始完成登录注册
准备工作:(1):配置Fresco图片显示,app包下创建一个类
public class MyApp extends Application{ @Override public void onCreate() { super.onCreate(); //配置 Fresco.initialize(this); } }然后到清单文件中,配置并且配置网络权限
<uses-permission android:name="android.permission.INTERNET" /> <application android:name=".app.MyApp" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">准备工作:(2):网络数据请求OKhttp+Retrofit+Rxjava封装,在retrofit包中分为三个类
public interface ApiService { @GET Observable<String> get(@Url String url, @QueryMap Map<String, String> map); @FormUrlEncoded @POST Observable<String> post(@Url String url, @FieldMap Map<String, String> map); }
public abstract class BaseObserver<T> implements Observer<String> { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(String s) { try { Type genType = getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); Class entityClass = (Class) params[0]; Gson gson = new Gson(); T t = (T)gson.fromJson(s,entityClass); success(t); } catch (Exception e) { failure(1001); e.printStackTrace(); } } @Override public void onError(Throwable e) { try { if(e != null){ if(e instanceof HttpException){ failure(HTTP_ERROR); } else if(e instanceof SocketException){ failure(NET_WORK_ERROR); }else { failure(UNKNOW_ERROR); } }else { failure(UNKNOW_ERROR); } e.printStackTrace() ; } catch (Exception e1) { failure(UNKNOW_ERROR); e1.printStackTrace(); } } @Override public void onComplete() { } // /** * code * 1000 UNKNOW_ERROR 未知错误 * 1001 json 转化异常 parse error * 1002 当前网络不可用 java.net.SocketException: Network is unreachable 超时 * 1003 服务器不可用 401 402 403 500 502 503 504 * @param code */ public static final int UNKNOW_ERROR = 1000; public static final int JSON_FORMAT_ERROR = 1001; public static final int NET_WORK_ERROR = 1002; public static final int HTTP_ERROR = 1003; public abstract void success(T t); public abstract void failure(int code); public abstract void onNext(LoginBean loginBean); public abstract void onNext(RegBean regBean); }
public class RetrofitManager { public static OkHttpClient client = new OkHttpClient.Builder() //添加拦截器 .addInterceptor(new MyInterceptor()) .build(); public static ApiService apiService = new Retrofit.Builder() .baseUrl("http://120.27.23.105/") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .client(client) .build() .create(ApiService.class); public static void get(String url, Map<String,String> map,Observer observer){ apiService.get(url,map) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer); } public static void post(String url,Map<String,String> map,Observer observer){ apiService.post(url,map) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer); } }如果接口需要上传公共参数,那么写一个拦截器类然后在retrofitmanneger类中如果添加拦截器即可(看注释)
拦截器
public class MyInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String string = request.url().url().toString(); String s = string + "&source=android"; Request request1 = request.newBuilder().url(s).build(); Response response = chain.proceed(request1); return response; } }
好了,现在开始进行项目编辑
1,登录页面布局
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:gravity="center" android:hint="请输入手机号" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:gravity="center" android:hint="请输入密码" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:gravity="center" android:orientation="horizontal"> <Button android:id="@+id/login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="登录" /> <Button android:id="@+id/reg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="注册" /> </LinearLayout> </LinearLayout>2,注册页面布局 activity_reg.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:gravity="center" android:hint="请输入手机号" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:gravity="center" android:hint="请输入密码" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:gravity="center" android:orientation="horizontal"> <Button android:id="@+id/login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="登录" /> <Button android:id="@+id/reg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="注册" /> </LinearLayout> </LinearLayout>3,登录的bean,view,model,presenter,Activity
public class LoginBean { /** * msg : 登录成功 * code : 0 * data : {"age":null,"appkey":"9cdef4b09eb65685","appsecret":"66B6E2E5F439618D01B67FBAEA31EFDA","createtime":"2018-01-17T13:50:29","email":null,"fans":null,"follow":null,"gender":null,"icon":null,"latitude":null,"longitude":null,"mobile":"18765432100","money":null,"nickname":null,"password":"473344696F4685CAE5B5B3C354BC77BE","praiseNum":null,"token":"AFD92DF6C6046F01B76D7C551AEC985B","uid":4362,"userId":null,"username":"18765432100"} */ private String msg; private String code; private 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 DataBean getData() { return data; } public void setData(DataBean data) { this.data = data; } public static class DataBean { /** * age : null * appkey : 9cdef4b09eb65685 * appsecret : 66B6E2E5F439618D01B67FBAEA31EFDA * createtime : 2018-01-17T13:50:29 * email : null * fans : null * follow : null * gender : null * icon : null * latitude : null * longitude : null * mobile : 18765432100 * money : null * nickname : null * password : 473344696F4685CAE5B5B3C354BC77BE * praiseNum : null * token : AFD92DF6C6046F01B76D7C551AEC985B * uid : 4362 * userId : null * username : 18765432100 */ private Object age; private String appkey; private String appsecret; private String createtime; private Object email; private Object fans; private Object follow; private Object gender; private Object icon; private Object latitude; private Object longitude; private String mobile; private Object money; private Object nickname; private String password; private Object praiseNum; private String token; private int uid; private Object userId; private String username; public Object getAge() { return age; } public void setAge(Object age) { this.age = age; } public String getAppkey() { return appkey; } public void setAppkey(String appkey) { this.appkey = appkey; } public String getAppsecret() { return appsecret; } public void setAppsecret(String appsecret) { this.appsecret = appsecret; } public String getCreatetime() { return createtime; } public void setCreatetime(String createtime) { this.createtime = createtime; } public Object getEmail() { return email; } public void setEmail(Object email) { this.email = email; } public Object getFans() { return fans; } public void setFans(Object fans) { this.fans = fans; } public Object getFollow() { return follow; } public void setFollow(Object follow) { this.follow = follow; } public Object getGender() { return gender; } public void setGender(Object gender) { this.gender = gender; } public Object getIcon() { return icon; } public void setIcon(Object icon) { this.icon = icon; } public Object getLatitude() { return latitude; } public void setLatitude(Object latitude) { this.latitude = latitude; } public Object getLongitude() { return longitude; } public void setLongitude(Object longitude) { this.longitude = longitude; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public Object getMoney() { return money; } public void setMoney(Object money) { this.money = money; } public Object getNickname() { return nickname; } public void setNickname(Object nickname) { this.nickname = nickname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Object getPraiseNum() { return praiseNum; } public void setPraiseNum(Object praiseNum) { this.praiseNum = praiseNum; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public Object getUserId() { return userId; } public void setUserId(Object userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } } }
public interface LoginIView { void success(LoginBean loginBean); void error(String e); String getPhone(); String getPwd(); }
public class LoginModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String phone,String pwd,final loginCallBack loginCallBack){ //把参数添加到集合中 map.put("mobile",phone); map.put("password",pwd); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("user/login", map, new BaseObserver<LoginBean>() { @Override public void success(LoginBean loginBean) { loginCallBack.success(loginBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface loginCallBack{ void success(LoginBean loginBean); void error(String e); } }
public class LoginPresenter { //定义出view层接口和model层类 LoginModel loginModel; LoginIView loginIView; //给构造器 public LoginPresenter(LoginIView loginIView, String md5) { this.loginIView = loginIView; this.loginModel = new LoginModel(); } //创建获取接口数据的方法 public void getDatas(){ String phone = loginIView.getPhone(); String pwd = loginIView.getPwd(); //调用model层获取数据的方法,将两个参数传进去 loginModel.getData(phone,pwd,new LoginModel.loginCallBack() { @Override public void success(LoginBean loginBean) { //这里进行了登录判断,是否可以正确跳转 if(loginBean.getMsg().length()==4){ //调用view层定义的方法 loginIView.success(loginBean); }else{ loginIView.error(loginBean.getMsg()); } } @Override public void error(String e) { } }); } }
创建MD5Helper类
public class MD5Helper { private static final char hexDigsits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; //封装的,获取md5的方法 public static String getMD5(String inStr){ //加密需要的字节数组,于是首先拿到内容的字节数组 byte [] inStrBytes=inStr.getBytes(); //消息摘要对象,指定为MD5方式 try { MessageDigest messageDigest=MessageDigest.getInstance("MD5"); //把摘要对象中的数据设置为我们的内容 messageDigest.update(inStrBytes); //拿到MD5算法的结果 byte [] messageDbytes=messageDigest.digest(); //我们把结果转化为16进制的格式 char [] str=new char[messageDbytes.length*2]; //循环是使用的角标 int k=0; for (int i = 0; i < messageDbytes.length; i++) { byte temp=messageDbytes[i]; //把一个字节分裂成两个部分,分别转化为十六进制的字符 str[k++]=hexDigsits[temp>>>4&0xf]; str[k++]=hexDigsits[temp&0xf]; } return new String(str); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } }
public class MainActivity extends AppCompatActivity implements LoginIView{ //使用第三方butterknife快速找到控件初始化控件 @BindView(R.id.phone) EditText phone; @BindView(R.id.password) EditText password; @BindView(R.id.login) Button login; @BindView(R.id.reg) Button reg; @BindView(R.id.activity_main) LinearLayout activityMain; private LoginPresenter loginPresenter; private String md5; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); //实例化P loginPresenter = new LoginPresenter(this,md5); } @OnClick({R.id.login, R.id.reg}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.login: //点击登录,创建MD5,上传给P层 md5 = MD5Helper.getMD5(password.getText().toString()); Toast.makeText(this, md5, Toast.LENGTH_SHORT).show(); loginPresenter.getDatas(); break; case R.id.reg: //点击注册跳转到注册页面 startActivity(new Intent(MainActivity.this, RegActivity.class)); break; } } @Override public void success(LoginBean loginBean) { //如果登录成功调转到商品列表 startActivity(new Intent(MainActivity.this, LieBiaoActivity.class)); Toast.makeText(this, loginBean.getMsg(), Toast.LENGTH_SHORT).show(); } @Override public void error(String e) { Toast.makeText(this, e, Toast.LENGTH_SHORT).show(); } @Override public String getPhone() { return phone.getText().toString(); } @Override public String getPwd() { return password.getText().toString(); } }4,注册的bean,view,model,presenter,Activity
public class RegBean { /** * msg : 天呢!用户名或密码不能为空 * code : 1 * data : {} */ private String msg; private String code; private String 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 String getData() { return data; } public void setData(String data) { this.data = data; } }
public interface RegIView { void success(RegBean regBean); void error(String e); String getPhone(); String getPwd(); }
public class RegModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String phone,String pwd,final RegCallBack regCallBack){ //添加到集合中 map.put("mobile",phone); map.put("password",pwd); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("user/reg", map, new BaseObserver<RegBean>() { @Override public void success(RegBean regBean) { regCallBack.success(regBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface RegCallBack{ void success(RegBean regBean); void error(String e); } }
public class RegPresenter { RegModel regModel; RegIView regIView; public RegPresenter(RegIView regIView) { this.regIView = regIView; this.regModel = new RegModel(); } public void getDatas(){ String phone = regIView.getPhone(); String pwd = regIView.getPwd(); regModel.getData(phone,pwd,new RegModel.RegCallBack() { @Override public void success(RegBean regBean) { regIView.success(regBean); } @Override public void error(String e) { regIView.error(e); } }); } }
public class RegActivity extends AppCompatActivity implements RegIView{ @BindView(R.id.phone) EditText phone; @BindView(R.id.password) EditText password; @BindView(R.id.reg) Button reg; @BindView(R.id.activity_main) LinearLayout activityMain; private RegPresenter regPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_reg); ButterKnife.bind(this); // regPresenter = new RegPresenter(this); } @OnClick(R.id.reg) public void onViewClicked() { regPresenter.getDatas(); } @Override public void success(RegBean regBean) { Toast.makeText(this, regBean.getMsg().toString()+regBean.getCode().toString(), Toast.LENGTH_SHORT).show(); } @Override public void error(String e) { } @Override public String getPhone() { return phone.getText().toString(); } @Override public String getPwd() { return password.getText().toString(); } }
五,商品列表
1,主布局activity_lie_biao.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/liebiao_recyclerview" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </LinearLayout>2,子布局item_liebiao.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="#ff00ff" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/liebiao_simp" android:layout_width="200dp" android:layout_height="200dp" /> <TextView android:id="@+id/liebiao_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="XXXXXXXXXXXXXXX"/> </LinearLayout>3,bean
public class LieBiaoBean { /** * msg : 请求成功 * code : 0 * data : [{"bargainPrice":99,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg","itemtype":1,"pid":45,"price":2999,"pscid":39,"salenum":4666,"sellerid":1,"subhead":"高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽!","title":"一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机"},{"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","itemtype":0,"pid":46,"price":234,"pscid":39,"salenum":868,"sellerid":2,"subhead":"【iPhone新品上市】新一代iPhone,让智能看起来更不一样","title":"Apple iPhone 8 Plus (A1864) 64GB 金色 移动联通电信4G手机"},{"bargainPrice":1599,"createtime":"2017-10-14T21:48:08","detailUrl":"https://item.m.jd.com/product/1993026402.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t5863/302/8961270302/97126/41feade1/5981c81cNc1b1fbef.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7003/250/1488538438/195825/53bf31ba/5981c57eN51e95176.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5665/100/8954482513/43454/418611a9/5981c57eNd5fc97ba.jpg!q70.jpg","itemtype":2,"pid":47,"price":111,"pscid":39,"salenum":757,"sellerid":3,"subhead":"碳黑色 32GB 全网通 官方标配 1件","title":"锤子 坚果Pro 特别版 巧克力色 酒红色 全网通 移动联通电信4G手机 双卡双待 碳黑色 32GB 全网通"},{"bargainPrice":3455,"createtime":"2017-10-14T21:38:26","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","itemtype":1,"pid":48,"price":222,"pscid":39,"salenum":656,"sellerid":4,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":1999,"createtime":"2017-10-10T16:09:02","detailUrl":"https://item.m.jd.com/product/5025971.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t7210/232/3738666823/232298/9004583e/59c3a9a7N8de42e15.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8356/82/2107423621/109733/c019b8c6/59c3a9a6Ne9a4bdd7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t10219/74/25356012/171379/7d55e296/59c3a9a8N82fa6e02.jpg!q70.jpg","itemtype":0,"pid":49,"price":333,"pscid":39,"salenum":123,"sellerid":5,"subhead":"vivo X20 带你开启全面屏时代!逆光也清晰,照亮你的美!","title":"vivo X20 全面屏手机 全网通 4GB+64GB 金色 移动联通电信4G手机 双卡双待"},{"bargainPrice":3455,"createtime":"2017-10-14T21:48:08","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","itemtype":2,"pid":50,"price":444,"pscid":39,"salenum":54,"sellerid":6,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":3455,"createtime":"2017-10-14T21:38:26","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","itemtype":1,"pid":51,"price":555,"pscid":39,"salenum":424,"sellerid":7,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"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","itemtype":0,"pid":52,"price":666,"pscid":39,"salenum":212,"sellerid":8,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":2999,"createtime":"2017-10-14T21:48:08","detailUrl":"https://item.m.jd.com/product/2385655.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t2068/298/2448145915/157953/7be197df/56d51a42Nd86f1c8e.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t2437/128/1687178395/117431/bcc190c1/56d3fcbaNb2963d21.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t2467/222/2263160610/95597/927b8a2f/56d3eafeNdecebeb6.jpg!q70.jpg","itemtype":2,"pid":53,"price":777,"pscid":39,"salenum":0,"sellerid":9,"subhead":"Super AMOLED三星双曲面2K 屏,支持无线充电!","title":"三星 Galaxy S7 edge(G9350)4GB+32GB 铂光金 移动联通电信4G手机 双卡双待"},{"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","itemtype":0,"pid":54,"price":888,"pscid":39,"salenum":7575,"sellerid":10,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"}] * page : 1 */ private String msg; private String code; private String page; 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 String getPage() { return page; } public void setPage(String page) { this.page = page; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * bargainPrice : 99.0 * createtime : 2017-10-14T21:38:26 * detailUrl : https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends * images : https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg * itemtype : 1 * pid : 45 * price : 2999.0 * pscid : 39 * salenum : 4666 * sellerid : 1 * subhead : 高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽! * title : 一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机 */ private double bargainPrice; private String createtime; private String detailUrl; private String images; private int itemtype; private int pid; private double price; private int pscid; private int salenum; 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 getItemtype() { return itemtype; } public void setItemtype(int itemtype) { this.itemtype = itemtype; } 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 getSalenum() { return salenum; } public void setSalenum(int salenum) { this.salenum = salenum; } 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; } } }
4,MVP
model层
public class LieBiaoModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String pscid,final LieBiaoCallBack lieBiaoCallBack){ //http://120.27.23.105/product/getProducts?pscid=39&page=1 //添加到集合中 map.put("pscid",pscid); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("product/getProducts", map, new BaseObserver<LieBiaoBean>() { @Override public void success(LieBiaoBean lieBiaoBean) { lieBiaoCallBack.success(lieBiaoBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface LieBiaoCallBack{ void success(LieBiaoBean lieBiaoBean); void error(String e); } }view层
public interface LieBiaoIView { void success(LieBiaoBean lieBiaoBean); void error(String e); }presenter层
public class LieBiaoPresenter { LieBiaoModel lieBiaoModel; LieBiaoIView lieBiaoIView; public LieBiaoPresenter(LieBiaoIView lieBiaoIView) { this.lieBiaoIView = lieBiaoIView; this.lieBiaoModel = new LieBiaoModel(); } //需要把接口中的参数传过来 public void getDatas(String pid){ lieBiaoModel.getData(pid,new LieBiaoModel.LieBiaoCallBack() { @Override public void success(LieBiaoBean lieBiaoBean) { lieBiaoIView.success(lieBiaoBean); } @Override public void error(String e) { } }); } /** * 解除绑定 */ public void dettach(){ this.lieBiaoIView=null; } }适配器
public class LieBiaoAdapter extends RecyclerView.Adapter<LieBiaoAdapter.ViewHolder> { //上下文和数据源 Context context; List<LieBiaoBean.DataBean> list; private View view; private GenericDraweeHierarchyBuilder builder; public LieBiaoAdapter(Context context, List<LieBiaoBean.DataBean> list) { this.context = context; this.list = list; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { view = LayoutInflater.from(context).inflate(R.layout.item_liebiao, parent, false); //返回对应的布局 return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, final int position) { //设置值 String[] split = list.get(position).getImages().split("\\|"); //ImageLoader.getInstance().displayImage(split[0],viewHolder.simpleDraweeView); Uri uri = Uri.parse(split[0]); builder = new GenericDraweeHierarchyBuilder(context.getResources()); RoundingParams params = RoundingParams.asCircle(); GenericDraweeHierarchy hierarchy = builder.setRoundingParams(params).build(); holder.liebiaoSimp.setHierarchy(hierarchy); holder.liebiaoSimp.setImageURI(uri); holder.liebiaoTitle.setText(list.get(position).getTitle()); //点击传值 view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pid = list.get(position).getPid(); Intent intent = new Intent(context,XiangQingActivity.class); intent.putExtra("pid",pid+""); context.startActivity(intent); } }); } @Override public int getItemCount() { return list==null?0:list.size(); } public class ViewHolder extends RecyclerView.ViewHolder { //第三方控件找布局 @BindView(R.id.liebiao_simp) SimpleDraweeView liebiaoSimp; @BindView(R.id.liebiao_title) TextView liebiaoTitle; public ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, view); } } }avtivity
public class LieBiaoActivity extends AppCompatActivity implements LieBiaoIView{ //new出集合 private List<LieBiaoBean.DataBean> list = new ArrayList<>(); @BindView(R.id.liebiao_recyclerview) RecyclerView liebiaoRecyclerview; private LieBiaoPresenter lieBiaoPresenter; private LieBiaoAdapter lieBiaoAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lie_biao); ButterKnife.bind(this); //初始化P层 lieBiaoPresenter = new LieBiaoPresenter(this); lieBiaoPresenter.getDatas("39"); //初始化适配器 lieBiaoAdapter = new LieBiaoAdapter(this,list); //设置适配器和布局管理器 liebiaoRecyclerview.setAdapter(lieBiaoAdapter); liebiaoRecyclerview.setLayoutManager(new LinearLayoutManager(this)); } @Override public void success(LieBiaoBean lieBiaoBean) { //添加数据 list.addAll(lieBiaoBean.getData()); lieBiaoAdapter.notifyDataSetChanged(); } @Override public void error(String e) { } @Override protected void onDestroy() { super.onDestroy(); lieBiaoPresenter.dettach(); } @Override protected void onResume() { super.onResume(); lieBiaoPresenter.getDatas("39"); } }六,商品详情
布局:activity_xiang_qing.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/newXiangQing_imageview" android:layout_marginTop="10dp" android:layout_gravity="center_horizontal" android:layout_width="300dp" android:layout_height="300dp" android:src="@mipmap/ic_launcher"/> <TextView android:layout_gravity="center_horizontal" android:id="@+id/newXiangQing_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" android:text="XXXXXXXXXX"/> <TextView android:layout_gravity="center_horizontal" android:id="@+id/newXiangQing_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" android:text="XXXXXXXXXX"/> <RelativeLayout android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content"> </RelativeLayout> <Button android:id="@+id/butn_addcar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/newXiangQing_butn_car" android:text="添加购物车" /> <Button android:id="@+id/butn_car" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="购物车" /> </LinearLayout>
1,bean
public class XiangQingBean { /** * msg : * seller : {"description":"我是商家17","icon":"http://120.27.23.105/images/icon.png","name":"商家17","productNums":999,"score":5,"sellerid":17} * code : 0 * data : {"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","itemtype":1,"pid":1,"price":118,"pscid":1,"salenum":0,"sellerid":17,"subhead":"每个中秋都不能简单,无论身在何处,你总需要一块饼让生活更圆满,京东月饼让爱更圆满京东自营,闪电配送,更多惊喜,快用手指戳一下","title":"北京稻香村 稻香村中秋节月饼 老北京月饼礼盒655g"} */ private String msg; private SellerBean seller; private String code; private DataBean data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public SellerBean getSeller() { return seller; } public void setSeller(SellerBean seller) { this.seller = seller; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public DataBean getData() { return data; } public void setData(DataBean data) { this.data = data; } public static class SellerBean { /** * description : 我是商家17 * icon : http://120.27.23.105/images/icon.png * name : 商家17 * productNums : 999 * score : 5.0 * sellerid : 17 */ private String description; private String icon; private String name; private int productNums; private double score; private int sellerid; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getProductNums() { return productNums; } public void setProductNums(int productNums) { this.productNums = productNums; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } public int getSellerid() { return sellerid; } public void setSellerid(int sellerid) { this.sellerid = sellerid; } } public static class DataBean { /** * 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 * itemtype : 1 * pid : 1 * price : 118.0 * pscid : 1 * salenum : 0 * sellerid : 17 * subhead : 每个中秋都不能简单,无论身在何处,你总需要一块饼让生活更圆满,京东月饼让爱更圆满京东自营,闪电配送,更多惊喜,快用手指戳一下 * title : 北京稻香村 稻香村中秋节月饼 老北京月饼礼盒655g */ private double bargainPrice; private String createtime; private String detailUrl; private String images; private int itemtype; private int pid; private double price; private int pscid; private int salenum; 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 getItemtype() { return itemtype; } public void setItemtype(int itemtype) { this.itemtype = itemtype; } 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 getSalenum() { return salenum; } public void setSalenum(int salenum) { this.salenum = salenum; } public int getSellerid() { return sellerid; } public void setSellerid(int sellerid) { this.sellerid = sellerid; } public String getSubhead() { return subhead; } public void setSubhead(String subhead) { this.subhead = subhead; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } }2,model层
public class XiangQingModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String pid,final XiangQingCallBack xiangQingCallBack){ //http://120.27.23.105/product/getProductDetail?pid=1 //添加到集合中 map.put("pid",pid); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("product/getProductDetail", map, new BaseObserver<XiangQingBean>() { @Override public void success(XiangQingBean xiangQingBean) { xiangQingCallBack.success(xiangQingBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface XiangQingCallBack{ void success(XiangQingBean xiangQingBean); void error(String e); } }3,view
public interface XiangQingIView { void success(XiangQingBean xiangQingBean); void error(String e); }4,presenter
public class XiangQingPresenter { XiangQingModel xiangQingModel; XiangQingIView xiangQingIView; public XiangQingPresenter(XiangQingIView xiangQingIView) { this.xiangQingIView = xiangQingIView; this.xiangQingModel = new XiangQingModel(); } //需要把接口中的参数传过来 public void getDatas(String pid){ xiangQingModel.getData(pid, new XiangQingModel.XiangQingCallBack() { @Override public void success(XiangQingBean xiangQingBean) { xiangQingIView.success(xiangQingBean); } @Override public void error(String e) { } }); } /** * 解除绑定 */ public void dettach(){ this.xiangQingIView=null; } }
注意:添加购物车也写在详情activity中
添加购物车bean
public class AddCarBean { /** * 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; } }添加购物车MVP
model
public class AddCarModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String uid,String pid,final AddCarCallBack addCarCallBack){ //http://120.27.23.105/product/addCart?uid=1&pid=1 //添加到集合中 map.put("uid",uid); map.put("pid",pid); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("product/addCart", map, new BaseObserver<AddCarBean>() { @Override public void success(AddCarBean addCarBean) { addCarCallBack.success(addCarBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface AddCarCallBack{ void success(AddCarBean addCarBean); void error(String e); } }view
public interface AddCarIView { void success(AddCarBean addCarBean); void error(String e); }presenter
public class AddCarPresenter { AddCarModel addCarModel; AddCarIView addCarIView; public AddCarPresenter(AddCarIView addCarIView) { this.addCarIView = addCarIView; this.addCarModel = new AddCarModel(); } //需要把接口中的参数传过来 public void getDatas(String uid,String pid){ addCarModel.getData(uid,pid, new AddCarModel.AddCarCallBack() { @Override public void success(AddCarBean addCarBean) { addCarIView.success(addCarBean); } @Override public void error(String e) { } }); } /** * 解除绑定 */ public void dettach(){ this.addCarIView=null; } }
5,activity
public class XiangQingActivity extends AppCompatActivity implements XiangQingIView,AddCarIView{ @BindView(R.id.newXiangQing_imageview) SimpleDraweeView newXiangQingImageview; @BindView(R.id.newXiangQing_title) TextView newXiangQingTitle; @BindView(R.id.newXiangQing_price) TextView newXiangQingPrice; @BindView(R.id.butn_addcar) Button butnAddcar; @BindView(R.id.butn_car) Button butnCar; private String pid; private XiangQingPresenter xiangQingPresenter; private GenericDraweeHierarchyBuilder builder; private AddCarPresenter addCarPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_xiang_qing); ButterKnife.bind(this); //接收到列表适配器中传过来的参数pid Intent intent = getIntent(); pid = intent.getStringExtra("pid"); //P xiangQingPresenter = new XiangQingPresenter(this); xiangQingPresenter.getDatas(pid + ""); //添加购物车P addCarPresenter = new AddCarPresenter(this); } @Override public void success(XiangQingBean xiangQingBean) { //设置值 String[] split = xiangQingBean.getData().getImages().split("\\|"); //ImageLoader.getInstance().displayImage(split[0],viewHolder.simpleDraweeView); Uri uri = Uri.parse(split[0]); builder = new GenericDraweeHierarchyBuilder(XiangQingActivity.this.getResources()); //圆形图片 RoundingParams params = RoundingParams.asCircle(); GenericDraweeHierarchy hierarchy = builder.setRoundingParams(params).build(); //setHierarchy newXiangQingImageview.setHierarchy(hierarchy); newXiangQingImageview.setImageURI(uri); newXiangQingTitle.setText("原价:" + xiangQingBean.getData().getPrice()); newXiangQingPrice.setText(xiangQingBean.getData().getTitle()); } @Override public void success(AddCarBean addCarBean) { Toast.makeText(this,addCarBean.getMsg(),Toast.LENGTH_SHORT).show(); } @Override public void error(String e) { } @Override protected void onDestroy() { super.onDestroy(); xiangQingPresenter.dettach(); addCarPresenter.dettach(); } @OnClick({R.id.butn_addcar, R.id.butn_car}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.butn_addcar: //点击添加购物车,显示加购提示 addCarPresenter.getDatas("100",pid+""); break; case R.id.butn_car: //点击购物车按钮,跳转到购物车页面 startActivity(new Intent(this,CartActivity.class)); break; } } }
七,购物车,购物车使用了自定义控件
1,自定义控件布局和实现类
自定义控件布局custom.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/custom_jian" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-"/> <EditText android:id="@+id/count_edtext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1"/> <Button android:id="@+id/custom_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+"/> </LinearLayout>
2,自定义控件实现类
public class CustomView extends LinearLayout { //定义输入框的默认值 int mcount = 1; Button customJian; EditText countEdtext; Button customAdd; public CustomView(Context context) { super(context); } public CustomView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); View view = View.inflate(context, R.layout.custom, null); //找到控件 customJian = view.findViewById(R.id.custom_jian); countEdtext = view.findViewById(R.id.count_edtext); customAdd = view.findViewById(R.id.custom_add); //减号的点击事件 customJian.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { //点击之前先拿到输入框里的值 String string = countEdtext.getText().toString().trim(); //转化数据类型 int count = Integer.valueOf(string); //如果输入框的数据大于1,点击减号的时候,就让其减少一 if (count>1){ mcount = count-1; countEdtext.setText(mcount+""); } //接口回调 if (jiaJian!=null){ jiaJian.dianji(mcount); } } }); //加号的点击事件 customAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { //点击之前先拿到输入框里的值 String string = countEdtext.getText().toString().trim(); //转化数据类型 int count = Integer.valueOf(string)+1; //如果输入框的数据大于1,点击减号的时候,就让其减少一 mcount = count; countEdtext.setText(mcount+""); //接口回调 if (jiaJian!=null){ jiaJian.dianji(mcount); } } }); //中间输入框内的变化 countEdtext.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { } }); addView(view); } public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //给输入框赋值的方法 public void setEditText(int num){ if(countEdtext != null){ countEdtext.setText(num+""); } } //加减号的点击事件接口 JiaJian jiaJian; public void setJiaJian(JiaJian jiaJian) { this.jiaJian = jiaJian; } public interface JiaJian{ public void dianji(int count); } }
3,购物车布局 activity_cart.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="385dp" android:layout_weight="0.77"> </android.support.v7.widget.RecyclerView> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <CheckBox android:layout_marginLeft="20dp" android:id="@+id/qunxuan_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全选"/> <LinearLayout android:layout_marginLeft="60dp" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/zongjia_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商品的总价:"/> <TextView android:id="@+id/zongshu_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商品的总数:"/> </LinearLayout> <Button android:layout_marginLeft="60dp" android:id="@+id/jiesuan_butn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="结算"/> </LinearLayout> </LinearLayout>4,购物车子布局 item_car.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <CheckBox android:id="@+id/shangjia_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/shangjia_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商家的名字"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <CheckBox android:layout_marginLeft="10dp" android:layout_gravity="center_vertical" android:id="@+id/shangpin_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:orientation="vertical"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/item_iamgeview" android:layout_width="50dp" android:layout_height="50dp" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/item_name_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商品的名字" /> <TextView android:id="@+id/item_price_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="商品的价格" /> <com.bawei.monimouth2.CustomView android:id="@+id/customview" android:layout_width="wrap_content" android:layout_height="50dp"> </com.bawei.monimouth2.CustomView> </LinearLayout> <Button android:layout_gravity="center_vertical" android:id="@+id/item_shanchu_butn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除"/> </LinearLayout> </LinearLayout>5,购物车bean
public class CarBean { /** * code : 0 * data : [{"list":[{"bargainPrice":99,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg","num":1,"pid":45,"price":2999,"pscid":39,"selected":0,"sellerid":1,"subhead":"高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽!","title":"一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机"}],"sellerName":"商家1","sellerid":"1"},{"list":[{"bargainPrice":3455,"createtime":"2017-10-14T21:38:26","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":48,"price":222,"pscid":39,"selected":0,"sellerid":4,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"}],"sellerName":"商家4","sellerid":"4"},{"list":[{"bargainPrice":3455,"createtime":"2017-10-14T21:48:08","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":2,"pid":50,"price":444,"pscid":39,"selected":0,"sellerid":6,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"}],"sellerName":"商家6","sellerid":"6"},{"list":[{"bargainPrice":3455,"createtime":"2017-10-14T21:38:26","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":51,"price":555,"pscid":39,"selected":0,"sellerid":7,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"}],"sellerName":"商家7","sellerid":"7"},{"list":[{"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":0,"sellerid":8,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"}],"sellerName":"商家8","sellerid":"8"}] * msg : 请求成功 */ private String code; private String msg; private List<DataBean> data; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * list : [{"bargainPrice":99,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg","num":1,"pid":45,"price":2999,"pscid":39,"selected":0,"sellerid":1,"subhead":"高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽!","title":"一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机"}] * sellerName : 商家1 * sellerid : 1 */ 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 { /** * bargainPrice : 99.0 * createtime : 2017-10-14T21:38:26 * detailUrl : https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends * images : https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg * num : 1 * pid : 45 * price : 2999.0 * pscid : 39 * selected : 0 * sellerid : 1 * subhead : 高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽! * title : 一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机 */ 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; private int isFirst; private boolean shangjiacheck; private boolean shangpincheck; public int getIsFirst() { return isFirst; } public void setIsFirst(int isFirst) { this.isFirst = isFirst; } public boolean isShangjiacheck() { return shangjiacheck; } public void setShangjiacheck(boolean shangjiacheck) { this.shangjiacheck = shangjiacheck; } public boolean isShangpincheck() { return shangpincheck; } public void setShangpincheck(boolean shangpincheck) { this.shangpincheck = shangpincheck; } 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; } } } }6,MVP
model
public class CarModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String uid,final CarCallBack carCallBack){ //http://120.27.23.105/product/getCarts?uid=100 //添加到集合中 map.put("uid",uid); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("product/getCarts", map, new BaseObserver<CarBean>() { @Override public void success(CarBean carBean) { carCallBack.success(carBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface CarCallBack{ void success(CarBean carBean); void error(String e); } }view
public interface CarIView { void success(CarBean carBean); void error(String e); }presenter
public class CarPresenter { CarModel carModel; CarIView carIView; public CarPresenter(CarIView carIView) { this.carIView = carIView; this.carModel = new CarModel(); } //需要把接口中的参数传过来 public void getDatas(String uid){ carModel.getData(uid, new CarModel.CarCallBack(){ @Override public void success(CarBean carBean) { carIView.success(carBean); } @Override public void error(String e) { } }); } /** * 解除绑定 */ public void dettach(){ this.carIView=null; } }7,适配器
public class CarAdapter extends RecyclerView.Adapter<CarAdapter.ViewHolder>{ //上下文和数据源 Context context; private List<CarBean.DataBean.ListBean> list; // 存放 商家的id 和 商家名称 private Map<String,String> map = new HashMap<>(); public CarAdapter(Context context) { this.context = context; } //把请求到的数据添加到集合中,并跟新 public void addData(CarBean carBean) { //如果集合是空的,就要先new出集合 if (list==null){ list = new ArrayList<>(); } //集合不为空的话,就要,添加到集合中 //便利商家,shangjia商家对象 for (CarBean.DataBean shangjia:carBean.getData()){ map.put(shangjia.getSellerid(),shangjia.getSellerName()); //便利出商品 for (int i=0;i<shangjia.getList().size();i++){ this.list.add(shangjia.getList().get(i)); } } //添加到view刚进去要显示 setFirst(this.list); //刷新数据 notifyDataSetChanged(); } //控制商家显示的方法 public void setFirst(List<CarBean.DataBean.ListBean> list){ /*bean中添加一个控制显示的属性isFirst, 1为显示,2为影藏 这个商家是否是第一个出现的,如果是就影藏,如果不是就展示*/ if (list.size()>0){ //数据第一个肯定是显示的 list.get(0).setIsFirst(1); //就要便利 集合中的商家去判断是不是第一个出现的 for (int i = 1;i<list.size();i++){ //如果当前的显示商家和后一条一样,就影藏 if (list.get(i).getSellerid() == list.get(i-1).getSellerid()){ //2是影藏 list.get(i).setIsFirst(2); }else{ //1是显示 list.get(i).setIsFirst(1); if (list.get(i).isShangpincheck()){ list.get(i).setShangjiacheck(list.get(i).isShangpincheck()); } } } } } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //创建布局 View view = View.inflate(context, R.layout.item_car,null); return new ViewHolder(view); } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { //填充值 //设置商家的多选框的状态 if (list.get(position).getIsFirst()==1){ //显示商家和商家名字 holder.shangjia_checkbox.setVisibility(View.VISIBLE); holder.shangjia_name.setVisibility(View.VISIBLE); //既然显示就给填充值,就需要有一个是否选中了这个多选框的属性,去bean添加 holder.shangjia_checkbox.setChecked(list.get(position).isShangjiacheck()); //设置商家的名字 holder.shangjia_name.setText(map.get(String.valueOf(list.get(position).getSellerid()))); }else{ //隐藏商家和商家名 holder.shangjia_checkbox.setVisibility(View.GONE); holder.shangjia_name.setVisibility(View.GONE); } //设置商品的多选框的状态 holder.shangpin_checkbox.setChecked(list.get(position).isShangpincheck()); //设置值 String[] split = list.get(position).getImages().split("\\|"); //ImageLoader.getInstance().displayImage(split[0],viewHolder.simpleDraweeView); Uri uri = Uri.parse(split[0]); holder.item_iamgeview.setImageURI(uri); //填充价格 holder.item_price_text.setText(list.get(position).getPrice()+""); //填充商品名称 holder.item_name_text.setText(list.get(position).getTitle()); //填充自定义控件中输入框的值 holder.customview.setEditText(list.get(position).getNum()); //删除的点击事件 holder.item_shanchu_butn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { list.remove(position); //删除以后显示第一个 // list.remove(position); setFirst(list); notifyDataSetChanged(); sum(list); } }); //加减号的点击事件 holder.customview.setJiaJian(new CustomView.JiaJian() { @Override public void dianji(int count) { //取到当前的数量 list.get(position).setNum(count); notifyDataSetChanged(); sum(list); } }); //商家的多选框框点击事件 holder.shangjia_checkbox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //商家的点击填充值 list.get(position).setShangjiacheck(holder.shangjia_checkbox.isChecked()); //遍历 for (int i=0;i<list.size();i++){ //如果当前的状态id和数据中的相对应,就说明选中了,商品也要选中 if (list.get(position).getSellerid()==list.get(i).getSellerid()){ list.get(i).setShangpincheck(holder.shangjia_checkbox.isChecked()); } } notifyDataSetChanged(); sum(list); } }); //商品的多选框点击事件 holder.shangpin_checkbox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //商品的点击填充值 list.get(position).setShangpincheck(holder.shangpin_checkbox.isChecked()); //遍历 for (int i=0;i<list.size();i++){ for (int j=0;j<list.size();j++){ //如果当前的状态id和数据中的相对应,并且不等于当前商品的点击状态 if(list.get(i).getSellerid() == list.get(j).getSellerid() && !list.get(j).isShangpincheck()){ //没有选中 list.get(i).setShangjiacheck(false); break; }else { //选中 list.get(i).setShangjiacheck(true); } } } notifyDataSetChanged(); sum(list); } });} //计算总价的方法, public void sum(List<CarBean.DataBean.ListBean> list){ int zongshu = 0; float zongjia = 0.0f; boolean allcheck = true; //循环计算 for (int i = 0;i<list.size();i++){ //如果有选中的商品,就计算 if (list.get(i).isShangpincheck()){ zongshu += list.get(i).getNum(); zongjia += list.get(i).getNum()*list.get(i).getPrice(); }else{ allcheck = false; } } //接口对象调用方法暴露数据 updataUi.gengxin(zongjia+"",zongshu+"",allcheck); } //全选的方法 public void selectAll(boolean check){ for(int i=0;i<list.size();i++){ //赋值的 list.get(i).setShangjiacheck(check); list.get(i).setShangpincheck(check); } notifyDataSetChanged(); sum(list); } /* //把请求到的数据添加到集合中,并跟新 public void addData(CarBean carBean) { //如果集合是空的,就要先new出集合 if (list==null){ list = new ArrayList<>(); } //集合不为空的话,就要,添加到集合中 //便利商家,shangjia商家对象 for (CarBean.DataBean shangjia:carBean.getData()){ map.put(shangjia.getSellerid(),shangjia.getSellerName()); //便利出商品 for (int i=0;i<shangjia.getList().size();i++){ this.list.add(shangjia.getList().get(i)); } } //添加到view刚进去要显示 setFirst(this.list); //刷新数据 notifyDataSetChanged(); } */ @Override public int getItemCount() { return list==null?0:list.size(); } public class ViewHolder extends RecyclerView.ViewHolder { private final CheckBox shangjia_checkbox; private final TextView shangjia_name; private final CheckBox shangpin_checkbox; private final SimpleDraweeView item_iamgeview; private final TextView item_name_text; private final TextView item_price_text; private final Button item_shanchu_butn; private final CustomView customview; public ViewHolder(View itemView) { super(itemView); //找到控件 shangjia_checkbox = itemView.findViewById(R.id.shangjia_checkbox); shangjia_name = itemView.findViewById(R.id.shangjia_name); shangpin_checkbox = itemView.findViewById(R.id.shangpin_checkbox); item_iamgeview = itemView.findViewById(R.id.item_iamgeview); item_name_text = itemView.findViewById(R.id.item_name_text); item_price_text = itemView.findViewById(R.id.item_price_text); customview = itemView.findViewById(R.id.customview); item_shanchu_butn = itemView.findViewById(R.id.item_shanchu_butn); } } //更新UI界面的接口,mvp模式,View层不做逻辑。。所以,最后回调给V层 public UpdataUi updataUi; public void setUpdataUi(UpdataUi updataUi) { this.updataUi = updataUi; } public interface UpdataUi{ //需要的参数为,总价格,总数量和是否全选 void gengxin(String zongjia, String zongshu, boolean allcheck); } }8,activity
public class CartActivity extends AppCompatActivity implements CarIView { @BindView(R.id.recyclerview) RecyclerView recyclerview; @BindView(R.id.qunxuan_checkbox) CheckBox qunxuanCheckbox; @BindView(R.id.zongjia_text) TextView zongjiaText; @BindView(R.id.zongshu_text) TextView zongshuText; @BindView(R.id.jiesuan_butn) Button jiesuanButn; private CarAdapter carAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cart); ButterKnife.bind(this); //P CarPresenter carPresenter = new CarPresenter(this); carPresenter.getDatas("100"); //适配器 carAdapter = new CarAdapter(this); //设置适配器和布局管理器 recyclerview.setAdapter(carAdapter); recyclerview.setLayoutManager(new LinearLayoutManager(this)); //调用适配器中的接口 carAdapter.setUpdataUi(new CarAdapter.UpdataUi() { @Override public void gengxin(String zongjia, String zongshu, boolean allcheck) { zongshuText.setText("件数:"+zongshu); zongjiaText.setText("总价:"+zongjia); qunxuanCheckbox.setChecked(allcheck); } }); } @Override public void success(CarBean carBean) { carAdapter.addData(carBean); carAdapter.notifyDataSetChanged(); } @Override public void error(String e) { } @OnClick({R.id.qunxuan_checkbox, R.id.jiesuan_butn}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.qunxuan_checkbox: selectAll(); break; case R.id.jiesuan_butn: startActivity(new Intent(this,DingDanActivity.class)); break; } } //全选的方法 private void selectAll() { carAdapter.selectAll(qunxuanCheckbox.isChecked()); } }
八,点击结算,跳转到订单页面
1,订单主页面布局 activity_ding_dan.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:textSize="25sp" android:textColor="#ff00" android:text="订单详情"/> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:background="@android:color/black"/> <RadioGroup android:id="@+id/rg" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_wait" android:layout_width="0dp" android:layout_weight="1" android:button="@null" android:gravity="center" android:textSize="15sp" android:layout_height="match_parent" android:text="待支付"/> <RadioButton android:id="@+id/rb_payed" android:layout_width="0dp" android:layout_weight="1" android:button="@null" android:gravity="center" android:textSize="15sp" android:layout_height="match_parent" android:text="已支付"/> <RadioButton android:id="@+id/rb_cancel" android:layout_width="0dp" android:layout_weight="1" android:button="@null" android:gravity="center" android:textSize="15sp" android:layout_height="match_parent" android:text="已取消"/> </RadioGroup> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:background="@android:color/black"/> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>2,每个fragment中布局是一样的,所以写一个就行,三个fragment公用一个布局fragment.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </FrameLayout>3,子布局item_dingdan.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/order_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginLeft="19dp" android:layout_marginStart="19dp" android:layout_marginTop="21dp" android:text="TextView" /> <TextView android:id="@+id/order_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/order_title" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_marginEnd="31dp" android:layout_marginRight="31dp" android:text="TextView" /> <TextView android:id="@+id/order_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/order_title" android:layout_alignStart="@+id/order_title" android:layout_below="@+id/order_title" android:layout_marginTop="27dp" android:text="TextView" /> <TextView android:id="@+id/order_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/order_price" android:layout_marginTop="24dp" android:text="TextView" /> <TextView android:id="@+id/order_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/order_time" android:layout_alignEnd="@+id/order_status" android:layout_alignRight="@+id/order_status" android:text="TextView" /> </RelativeLayout>
4,创建三个fragment
public class CanceldFragment extends Fragment implements DingDanIView{ //创建集合 private List<DingDanBean.DataBean> list = new ArrayList<>(); private DingDanPresenter dingDanPresenter; private DingDanFragmentAdapter dingDanFragmentAdapter; private RecyclerView recy_cancel; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //创建布局,找到控件 View view=inflater.inflate(R.layout.fragment, container, false); recy_cancel = view.findViewById(R.id.recyclerView); //实例P dingDanPresenter = new DingDanPresenter(this); //参数赋值 dingDanPresenter.getDatas("100","1"); //初始化适配器 dingDanFragmentAdapter = new DingDanFragmentAdapter(getContext(),list); //设置适配器和布局管理器 recy_cancel.setAdapter(dingDanFragmentAdapter); recy_cancel.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL,false)); return view; } @Override public void success(DingDanBean dingDanBean) { //进来先清空缓存 list.clear(); list.addAll(dingDanBean.getData()); //刷新 dingDanFragmentAdapter.notifyDataSetChanged(); } @Override public void error(String e) { } //防止内存泄漏 @Override public void onDestroy() { super.onDestroy(); dingDanPresenter.dettach(); } }
public class PayedFragment extends Fragment implements DingDanIView{ //创建集合 private List<DingDanBean.DataBean> list = new ArrayList<>(); private DingDanPresenter dingDanPresenter; private DingDanFragmentAdapter dingDanFragmentAdapter; private RecyclerView recy_cancel; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //创建布局,找到控件 View view=inflater.inflate(R.layout.fragment, container, false); recy_cancel = view.findViewById(R.id.recyclerView); //实例P dingDanPresenter = new DingDanPresenter(this); //参数赋值 dingDanPresenter.getDatas("100","2"); //初始化适配器 dingDanFragmentAdapter = new DingDanFragmentAdapter(getContext(),list); //设置适配器和布局管理器 recy_cancel.setAdapter(dingDanFragmentAdapter); recy_cancel.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL,false)); return view; } @Override public void success(DingDanBean dingDanBean) { //进来先清空缓存 list.clear(); list.addAll(dingDanBean.getData()); //刷新 dingDanFragmentAdapter.notifyDataSetChanged(); } @Override public void error(String e) { } //防止内存泄漏 @Override public void onDestroy() { super.onDestroy(); dingDanPresenter.dettach(); } }
public class WaitPayFragment extends Fragment implements DingDanIView { //创建集合 private List<DingDanBean.DataBean> list = new ArrayList<>(); private DingDanPresenter dingDanPresenter; private DingDanFragmentAdapter dingDanFragmentAdapter; private RecyclerView recy_cancel; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //创建布局,找到控件 View view=inflater.inflate(R.layout.fragment, container, false); recy_cancel = view.findViewById(R.id.recyclerView); //实例P dingDanPresenter = new DingDanPresenter(this); //参数赋值 dingDanPresenter.getDatas("100","0"); //初始化适配器 dingDanFragmentAdapter = new DingDanFragmentAdapter(getContext(),list); //设置适配器和布局管理器 recy_cancel.setAdapter(dingDanFragmentAdapter); recy_cancel.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL,false)); return view; } @Override public void success(DingDanBean dingDanBean) { //进来先清空缓存 list.clear(); list.addAll(dingDanBean.getData()); //刷新 dingDanFragmentAdapter.notifyDataSetChanged(); } @Override public void error(String e) { } //防止内存泄漏 @Override public void onDestroy() { super.onDestroy(); dingDanPresenter.dettach(); } }
5,订单bean
public class DingDanBean { /** * msg : 请求成功 * code : 0 * data : [{"createtime":"2017-10-19T20:28:43","orderid":20,"price":100,"status":2,"title":"订单标题测试3","uid":71},{"createtime":"2017-10-19T20:44:40","orderid":31,"price":11800,"status":2,"title":"订单标题测试14","uid":71},{"createtime":"2017-10-19T20:44:51","orderid":32,"price":11800,"status":2,"title":"订单标题测试15","uid":71},{"createtime":"2017-10-20T08:02:07","orderid":43,"price":11800,"status":2,"title":"订单标题测试","uid":71},{"createtime":"2017-10-20T08:02:16","orderid":44,"price":11800,"status":2,"title":"订单标题测试","uid":71},{"createtime":"2017-10-22T15:14:39","orderid":890,"price":11800,"status":2,"title":"","uid":71},{"createtime":"2017-11-09T09:17:20","orderid":1446,"price":99.99,"status":1,"title":"订单标题测试","uid":71},{"createtime":"2017-11-09T09:20:58","orderid":1447,"price":567,"status":2,"title":"订单标题测试","uid":71},{"createtime":"2017-11-09T09:20:58","orderid":1448,"price":256.99,"status":2,"title":"订单标题测试","uid":71},{"createtime":"2017-11-09T09:20:58","orderid":1449,"price":399,"status":2,"title":"订单标题测试","uid":71}] * page : 1 */ private String msg; private String code; private String page; 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 String getPage() { return page; } public void setPage(String page) { this.page = page; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * createtime : 2017-10-19T20:28:43 * orderid : 20 * price : 100.0 * status : 2 * title : 订单标题测试3 * uid : 71 */ private String createtime; private int orderid; private double price; private int status; private String title; private int uid; public String getCreatetime() { return createtime; } public void setCreatetime(String createtime) { this.createtime = createtime; } public int getOrderid() { return orderid; } public void setOrderid(int orderid) { this.orderid = orderid; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } } }6,MVP
model
public class DingDanModel { //创建一个Map集合 Map<String,String> map = new HashMap<>(); //获取数据的方法 public void getData(String uid,String status,final DingDanCallBack dingDanCallBack){ //http://120.27.23.105/product/getOrders?uid=71 //添加到集合中 map.put("uid",uid); //添加状态值 map.put("status",status); //使用封装进行请求数据,第一个参数为接口域名以后的部分,第二参数为map集合,第三个参数为回调接口 RetrofitManager.get("product/getOrders", map, new BaseObserver<DingDanBean>() { @Override public void success(DingDanBean dingDanBean) { dingDanCallBack.success(dingDanBean); } @Override public void failure(int code) { } @Override public void onNext(LoginBean loginBean) { } @Override public void onNext(RegBean regBean) { } }); } //创建model层的回调接口 public interface DingDanCallBack{ void success(DingDanBean dingDanBean); void error(String e); } }view
public interface DingDanIView { void success(DingDanBean dingDanBean); void error(String e); }presenter
public class DingDanPresenter { DingDanModel dingDanModel; DingDanIView dingDanIView; public DingDanPresenter(DingDanIView dingDanIView) { this.dingDanIView = dingDanIView; this.dingDanModel = new DingDanModel(); } //需要把接口中的参数传过来 public void getDatas(String uid,String status){ dingDanModel.getData(uid,status, new DingDanModel.DingDanCallBack(){ @Override public void success(DingDanBean dingDanBean) { dingDanIView.success(dingDanBean); } @Override public void error(String e) { } }); } /** * 解除绑定 */ public void dettach(){ this.dingDanIView=null; } }7,fragment中的适配器
public class DingDanFragmentAdapter extends RecyclerView.Adapter<DingDanFragmentAdapter.ViewHolder>{ //上下文和数据源 private Context context; private List<DingDanBean.DataBean> list; public DingDanFragmentAdapter(Context context, List<DingDanBean.DataBean> list) { this.context = context; this.list = list; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View inflate = LayoutInflater.from(context).inflate(R.layout.item_dingdan, null); return new ViewHolder(inflate); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { DingDanBean.DataBean dataBean = list.get(position); //赋值 holder.orderTime.setText("创建时间:"+dataBean.getCreatetime()); holder.orderTitle.setText(dataBean.getTitle()+""); holder.orderPrice.setText("优惠价:¥"+dataBean.getPrice()+""); //设置字体颜色 holder.orderPrice.setTextColor(Color.RED); //定义状态 int status = dataBean.getStatus(); holder.orderStatus.setTextColor(Color.parseColor("#000000")); //设置订单状态 if(status==0){ holder.orderStatus.setTextColor(Color.parseColor("#ff0000")); holder.orderStatus.setText("待支付"); holder.orderBtn.setText("取消订单"); }else if(status==1){ holder.orderStatus.setText("已取消"); holder.orderBtn.setText("查看订单"); }else if(status==2){ holder.orderStatus.setText("已支付"); holder.orderBtn.setText("查看订单"); } //点击监听 holder.orderBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.i("onClick: ","======================="); //创建弹窗提示 AlertDialog.Builder dialog=new AlertDialog.Builder(context); //设置弹窗标题 dialog.setTitle("提示") .setMessage("确定取消订单吗?") .setNegativeButton("取消", new DialogInterface.OnClickListener() { //点击取消后的逻辑 @Override public void onClick(DialogInterface dialog, int which) { } }) .setPositiveButton("确定", new DialogInterface.OnClickListener() { //点击确定后的逻辑 @Override public void onClick(DialogInterface dialog, int which) { holder.orderStatus.setTextColor(Color.parseColor("#000000")); holder.orderStatus.setText("已取消"); } }).create().show(); } }); } @Override public int getItemCount() { return list==null?0:list.size(); } //找到控件,初始化控件 public class ViewHolder extends RecyclerView.ViewHolder { private final TextView orderTitle; private final TextView orderPrice; private final TextView orderTime; private final TextView orderStatus; private final TextView orderBtn; public ViewHolder(View itemView) { super(itemView); orderTitle = itemView.findViewById(R.id.order_title); orderPrice = itemView.findViewById(R.id.order_price); orderTime = itemView.findViewById(R.id.order_time); orderStatus = itemView.findViewById(R.id.order_status); orderBtn = itemView.findViewById(R.id.order_btn); } } }
8,activity
public class DingDanActivity extends AppCompatActivity { @BindView(R.id.rb_wait) RadioButton rbWait; @BindView(R.id.rb_payed) RadioButton rbPayed; @BindView(R.id.rb_cancel) RadioButton rbCancel; @BindView(R.id.rg) RadioGroup rg; @BindView(R.id.viewpager) ViewPager viewpager; //创建集合 private List<Fragment> list; private MyApapter myApapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ding_dan); ButterKnife.bind(this); //初始化集合并添加Fragment对象 list = new ArrayList<>(); list.add(new WaitPayFragment()); list.add(new PayedFragment()); list.add(new CanceldFragment()); //初始化viewpage的适配器 myApapter = new MyApapter(getSupportFragmentManager()); //设置适配器 viewpager.setAdapter(myApapter); } //监听事件 @OnClick({R.id.rb_wait, R.id.rb_payed, R.id.rb_cancel}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.rb_wait: viewpager.setCurrentItem(0); break; case R.id.rb_payed: viewpager.setCurrentItem(1); break; case R.id.rb_cancel: viewpager.setCurrentItem(2); break; } } //创建viewpage适配器 class MyApapter extends FragmentPagerAdapter { public MyApapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return list.get(position); } @Override public int getCount() { return list.size(); } } }
运行,收工。