你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
首页
热门
推荐
精选
登录
|
注册
Mvp快速搭建商城购物车模块
立即下载
用AI写一个
该例子支持:好用才打赏哦
现在下载学习
发布时间:2018-04-25
22人
|
浏览:2626次
|
收藏
|
分享
技术:android mvp架构思想
运行环境:android studio+android sdk25
概述
通过mvp的思想搭建大家常用的购物车模块
详细
###前言: 说到`MVP`的时候其实大家都不陌生,但是涉及到实际项目中使用,还是有些无从下手。因此这里小编带着大家一步步地如何用`MVP`去搭建购物车模块。 首先还是按照惯例,用一张实现的动态图来说明吧: ![demo.gif](/contentImages/image/jianshu/2528336-ada175fac0ded8e0.gif) 看图其实可以看得出来咱们这块的功能主要有: - 单个店面的选择 - 某个店面下对某个商品的选择 - 对某个店面里某个商品数量的增减 - 最下面的商品全选 - 对选中的商品价格的计算 - 对选中商品进行结算(主要给服务器那边) ### 实现: 说完了要实现的功能,紧接着就要去分析,咱们的`MVP`的架子该如何去分析呢: 首先来看M层,大家都知道M层是数据层,是操作数据的关键层,那咱们这块主要有**获取商品**、**单个商品的增减**、**单个商品的选中取消**、**单个店的选中取消**、**所有商品的全选取消**,V层就是显示这层了,这里就定义了几种情况,**成功获取到商品**、**显示修改时显示某个商品**、**显示错误页面**、**显示空的页面**,P层就是两个层的桥梁了 对view层进行回调显示了。 这里画一张结构图,来说明`MVP`的特点: ![购物车类结构图.png](/contentImages/image/jianshu/2528336-ea5f3cfd8a3bc34f.png) 从图中大家可以看得出来,首先是定义好咋们的`IMode`接口,接口里面只有一个获取所有的商品方法: ``` //需要传入数据的类型,该类承担着从网络或本地获取数据的部分 public interface IMode
{ void loadList(); } ``` 紧接着就是咋们的`ShopMode`实现类了: ``` //当前每次需要回调的价格变量 private double price; private List
select_list = new ArrayList<>();//传到结算页面的商品数据 private List
allShopCarBean = new ArrayList<>();//传到结算页面的商品数据 ``` ``` //获取的数据源部分,从Asset目录下面的shopcartdata.json获取,获取成功后,将数据交给了回调接口,并且将获取到的数据放到allShopCarBean集合里面 @Override public void loadList() { StringBuilder stringBuilder = new StringBuilder(); try { AssetManager assetManager = context.getAssets(); BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open("shopcartdata.json"))); String line; while ((line = bf.readLine()) != null) { stringBuilder.append(line); } String json = stringBuilder.toString(); Gson gson = new Gson(); List
list = gson.fromJson(json, new TypeToken
>() { }.getType());//对于不是类的情况,用这个参数给出 listener.loadSuccess(list); allShopCarBean.addAll(list); } catch (Exception e) { e.printStackTrace(); } } ``` ``` //点击了某个店面下的某个商品的数量减少, parent_position:店面的id, child_position:商品的id public void numberReduce(int parent_position, int child_position) { ShopCartBean bean = allShopCarBean.get(parent_position); List
goodsList = bean.getGoods(); GoodsBean goodsBean = goodsList.get(child_position); String goods_num = goodsBean.getGoods_number(); int goodsNum = Integer.parseInt(goods_num); boolean canReduce = false; if (goodsNum > 1) { canReduce = true; } //通过id获取相应的商品 GoodsBean selectGoodsBean = goodsNumChange(2, parent_position, child_position); Log.d(TAG, "goodsBean.number:" + goodsBean.getGoods_number()); if (selectGoodsBean.isCheck() && canReduce) { //价格需要在前面的基础上减去单个商品的价格,相当于数量减少了一个 price -= Double.parseDouble(selectGoodsBean.getGoods_price()); Log.d(TAG, "price:" + price); listener.onNumberReduce(price, select_list); } } ``` ``` //商品数量的增减并且返回选中的GoodsBean private GoodsBean goodsNumChange(int type, int parent_position, int child_position) { ShopCartBean bean = allShopCarBean.get(parent_position); List
goodsList = bean.getGoods(); GoodsBean goodsBean = goodsList.get(child_position); String goods_num = goodsBean.getGoods_number(); int goodsNum = Integer.parseInt(goods_num); if (type == 1) { goodsNum = goodsNum + 1; } else { if (goodsNum > 1) { goodsNum = goodsNum - 1; } } goodsBean.setGoods_number(String.valueOf(goodsNum)); ShopCartBean selectBean = new ShopCartBean(); //对当前的选中的ShopCartBean进行重新给值 selectBean.clearGoods(bean, select_list); //如果之前在select_list中存在,移除之前的,将新的放到该集合中 int index = isContainsShopBean(select_list, selectBean); if (index != -1) { select_list.remove(index); } select_list.add(selectBean); listener.onNumberChange(parent_position); return goodsBean; } ``` ``` //判断当前的shopCartBean是否在之前选中的集合中 private int isContainsShopBean(List
existShopBeanList, ShopCartBean shopCartBean) { for (int i = 0; i < existShopBeanList.size(); i++) { ShopCartBean selectBean = existShopBeanList.get(i); Log.d(TAG, "selectBean.getSupplier_id" + selectBean.getSupplier_id()); Log.d(TAG, "shopCartBean.getSupplier_id" + shopCartBean.getSupplier_id()); if (selectBean.getSupplier_id().equals(shopCartBean.getSupplier_id())) { return i; } } return -1; } ``` ``` //点击了某一个店面,此时就是全选当前店面下的商品或是全消店面下面的商品 public void itemChildClick(int position) { ShopCartBean bean = allShopCarBean.get(position); //如果之前存在当前的ShopCartBean则进行移除操作 int index = isContainsShopBean(select_list, bean); if (index != -1) { select_list.remove(index); } boolean isSelected; boolean checkAll; //选中与未选中做取反操作 if (bean.isCheck()) { isSelected = false; } else { isSelected = true; } //保存店铺点击状态 bean.setCheck(isSelected); //通知全选CheckBox的选择状态,看是不是全选的 if (allSelect() == allShopCarBean.size()) { checkAll = true; } else { checkAll = false; } //这里如果是选中了某一个店,需要对这个店下面的商品总价格加操作 if (isSelected) { for (int i = 0; i < bean.getGoods().size(); i++) { //只有在没选中的情况下才会去修改状态以及总价格 if (!bean.getGoods().get(i).isCheck()) { bean.getGoods().get(i).setCheck(true); price += Double.parseDouble(bean.getGoods().get(i).getGoods_number()) * Double.parseDouble(bean.getGoods().get(i).getGoods_price()); } } select_list.add(bean); } else { // 解决点击取消选择商品时,店铺全选按钮取消选择状态,不会不变成全不选 if (allChildSelect(position) == bean.getGoods().size()) { for (int i = 0; i < bean.getGoods().size(); i++) { //只有在选中情况下才会去修改状态以及总价格 if (bean.getGoods().get(i).isCheck()) { bean.getGoods().get(i).setCheck(false); price -= Double.parseDouble(bean.getGoods().get(i).getGoods_number()) * Double.parseDouble(bean.getGoods().get(i).getGoods_price()); } } select_list.remove(bean); } } listener.onItemChildClick(price, checkAll, select_list, position); } ``` ``` //对某一个商品进行选中与未选中 public void childClick(int parent_position, int child_position) { ShopCartBean bean = allShopCarBean.get(parent_position); ShopCartBean selectBean = new ShopCartBean(); selectBean.clearGoods(bean, select_list); List
goodsList = bean.getGoods(); GoodsBean goodsBean = goodsList.get(child_position); boolean isSelected; boolean checkAll; if (goodsBean.isCheck()) { isSelected = false; price -= Double.parseDouble(goodsBean.getGoods_number()) * Double.parseDouble(goodsBean.getGoods_price()); selectBean.getGoods().remove(goodsBean); } else { isSelected = true; price += Double.parseDouble(goodsBean.getGoods_number()) * Double.parseDouble(goodsBean.getGoods_price()); selectBean.getGoods().add(goodsBean); } //保存商品点击状态 goodsBean.setCheck(isSelected); //通知店铺选择的状态 if (allChildSelect(parent_position) == goodsList.size()) { bean.setCheck(true); selectBean.setCheck(true); } else { bean.setCheck(false); selectBean.setCheck(false); } int index = isContainsShopBean(select_list, selectBean); if (index != -1) { select_list.remove(index); } select_list.add(selectBean); //通知全选CheckBox的选择状态 if (allSelect() == allShopCarBean.size()) { checkAll = true; } else { checkAll = false; } listener.onItemChildClick(price, checkAll, select_list, parent_position); } ``` ``` //所有的店面下面所有的商品选中的操作 public void selectAll() { price = 0; select_list.clear(); for (int i = 0; i < allShopCarBean.size(); i++) { ShopCartBean shopCartBean = allShopCarBean.get(i); //选择店铺 if (!shopCartBean.isCheck()) { shopCartBean.setCheck(true); } for (int j = 0; j < shopCartBean.getGoods().size(); j++) { //选择店铺的商品 if (!shopCartBean.getGoods().get(j).isCheck()) { shopCartBean.getGoods().get(j).setCheck(true); Log.d(TAG, "数量:" + shopCartBean.getGoods().get(j).getGoods_number()); } price += Double.parseDouble(shopCartBean.getGoods().get(j).getGoods_number()) * Double.parseDouble(shopCartBean.getGoods().get(j).getGoods_price()); } select_list.add(shopCartBean); } listener.onSelctAll(price, select_list); } ``` ``` //取消全选的操作 public void unSelectAll() { if (allSelect() == allShopCarBean.size()) { for (int i = 0; i < allShopCarBean.size(); i++) { ShopCartBean shopCartBean = allShopCarBean.get(i); if (shopCartBean.isCheck()) { shopCartBean.setCheck(false); } for (int j = 0; j < shopCartBean.getGoods().size(); j++) { if (shopCartBean.getGoods().get(j).isCheck()) { shopCartBean.getGoods().get(j).setCheck(false); } } } select_list.clear(); price = 0; listener.onUnSelectAll(price, select_list); } } ``` ``` //某个店面下,某个商品数量加的操作 public void numberAdd(int parent_position, int child_position) { GoodsBean goodsBean = goodsNumChange(1, parent_position, child_position); if (goodsBean.isCheck()) { price += Double.parseDouble(goodsBean.getGoods_price()); listener.onNumberAdd(price, select_list); } } ``` 关于`mode`层的业务逻辑就是这么多了,下面就是搭建p层了,看下p层的接口: ``` public interface Presenter { public void presenterList(); } ``` 这里就定义了一个方法,主要是去看下它的子类: ``` public class ShopCarPresenter implements IPresenter, ShopLoaderListener { //持有view层的接口,需要v层传进来 IView view; //持有mode层的接口,此处在该类直接生成 Mode mode; public ShopCarPresenter(Context context, IView view) { this.view = view; this.mode = new ShopMode(context, this); } } ``` 其实对于p层有两种操作,一种是不对view层进行回调的操作,一种是需要对view层进行回调,由于这里分两种情况,因此这里就举例说明: ``` //看到没就是这么简单的一句,不带回调到view层的 @Override public void presenterList() { mode.loadList(); } ``` ``` //也是一句,调用了ShopCartFragment的方法 @Override public void onNumberAdd(double price, List
select_list) { if (view instanceof ShopCartFragment) { ((ShopCartFragment) view).numberAdd(price, select_list); } } ``` **总的来说,p层是我们最简单的一层,因为它只是建立view层和mode层的桥梁,持有他们的实例。** 下面再来看看view层的定义,看下接口: ``` public interface IView
{ public void showSuccessPage(List
list); public void showSuccessPage(T t); public void showErrorPage(); public void showEmptyPage(); } ``` 这里方法就根据自己业务写方法了,其实我这里也是没必要定义那么多方法的,真正用到了就上面两个方法。 咋们这里view层的实例就是ShopCartFragment了,咋们可以看看它的定义: ![ShopCartFragment类定义.png](/contentImages/image/jianshu/2528336-6c52f5ce3a5e3c4c.png) 其实就是对Iview实现,然后在不同的实现方法里面处理view,所以在view的实现类里面不会出现处理业务的代码,只会跟view相关的代码。 ### 代码补充说明: > 项目代码比较多,这个是没办法全部贴出来,以上是模型的实现代码,具体的代码结构,见 项目结构图,以及具体的项目代码包 ###项目结构图: ![](/contentImages/image/20180424/jQfSHM4AyBRloKHmX02.jpg)
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
感谢
7
手机上随时阅读、收藏该文章 ?请扫下方二维码
相似例子推荐
评论
作者
随风者
购买服务
购买服务
服务描述:
demo不懂的地方可以讲给你听
服务价格:
¥10
我要联系
6
例子数量
107
帮助
22
感谢
评分详细
可运行:
4.5
分
代码质量:
4.5
分
文章描述详细:
4.5
分
代码注释:
4.5
分
综合:
4.5
分
作者例子
苹果版小黄车(ofo)app主页菜单效果
一分钟搞定触手app主页酷炫滑动切换效果
3D版翻页公告效果
定制一个类似地址选择器的view
仿360手机助手下载按钮
Mvp快速搭建商城购物车模块