转载请注明本文出自JFlex的博客http://blog.csdn.net/jflex/article/details/46653309,请尊重他人的辛勤劳动成果,谢谢!

Android快速开发之appBase——实战《购物车》

最近将appBase实战于各种项目中,也发现了不少问题,并优化了很多功能。今天带给大家一个实战–《购物车》。购物车,在商城app中是必不可少的一部分,也是使用的比较多的,这里简单的做一个效果。

先来看看效果图

1、创建项目

第一种、引用appBase项目即可

第二种、将appBase的jar文件copy到libs下


我用的第二种,如上图所示。


2、代码生成

通过代码生成器生成Activity、Presenter、Adapter

1、生成Activity(默认生成Presenter)

2、生成Adapter


3、网络请求数据

这里网络数据使用的是APICloud,那么就需要对于APICloudSDK进行配置。最新的appBase讲配置放了出来,只要在applcation中进行代码配置就可以了。


package com.example.shopcartdemo;import com.apicloud.sdk.APICloudSDK;
import com.snicesoft.Application;
import com.snicesoft.http.HttpReq;public class MyApplication extends Application {final String APP_ID = "A6960031839242";final String APP_KEY = "3F248D5F-50DB-782A-F437-E13796238B9E";@Overridepublic void onCreate() {super.onCreate();APICloudSDK.getInstance().init(APP_ID, APP_KEY);APICloudSDK.getInstance().init(hu());HttpReq.debug = true;}
}

这里添加了DialogPresenter,作用就是为了请求的时候对dialog的控制

DialogPresenter


package com.example.shopcartdemo.presenter;import android.app.ProgressDialog;
import android.content.Context;import com.snicesoft.presenter.BasePresenter;
import com.snicesoft.util.DialogUtil;public class DialogPresenter<C extends BasePresenter.Callback> extendsBasePresenter<C> {public DialogPresenter(Context context) {super(context);progressDialog = DialogUtil.getProgressDialog(context);}ProgressDialog progressDialog;protected void showDialog(CharSequence message, boolean... flag) {if (flag != null) {if (flag.length > 0)progressDialog.setCancelable(flag[0]);if (flag.length > 1)progressDialog.setCanceledOnTouchOutside(flag[1]);}progressDialog.setMessage(message);if (!progressDialog.isShowing())progressDialog.show();}protected void closeDialog() {if (progressDialog.isShowing())progressDialog.dismiss();}
}

MainPresenter


package com.example.shopcartdemo.presenter;import java.util.ArrayList;
import java.util.List;import android.content.Context;import com.alibaba.fastjson.JSON;
import com.apicloud.sdk.APICloudSDK;
import com.example.shopcartdemo.adapter.ShopCartAdapter;
import com.lidroid.xutils.exception.HttpException;
import com.snicesoft.http.HttpCallback;
import com.snicesoft.presenter.BasePresenter;
import com.snicesoft.util.CommonUtils;public class MainPresenter extends DialogPresenter<MainPresenter.Callback> {public MainPresenter(Context context) {super(context);}public interface Callback extends BasePresenter.Callback {void setShopCartList(List<ShopCartAdapter.Data> list);}public static class ShopCart {String title;int price;int count;public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}}public void getShopCartList() {showDialog("正在加载");APICloudSDK.getInstance().GET("/mcm/api/ShopCart?filter=%7B%22where%22%3A%7B%7D%2C%22skip%22%3A0%2C%22limit%22%3A20%7D",null, new HttpCallback() {@Overridepublic void onSuccess(String result) {closeDialog();List<ShopCart> array = JSON.parseArray(result,ShopCart.class);List<ShopCartAdapter.Data> list = new ArrayList<ShopCartAdapter.Data>();for (ShopCart cart : array) {list.add(new ShopCartAdapter.Data(0,cart.title,cart.price,"http://ck.haier.com/UpLoad/2015-05-15/a5e8cac4-2671-4aa0-83a7-66c64e051f95.jpg",cart.count));}if (callback != null)callback.setShopCartList(list);}@Overridepublic void onFailure(HttpException arg0) {closeDialog();CommonUtils.showToast(getContext(), "请求失败,请稍后重试");}});}
}

在这个类中,网络请求和网络解析实体对象都用内部类来定义,注意:内部类定义一定要用static class,否则fastjson无法正常解析,会导致无法反射创建对象。


4、数据绑定和交互

首先看下Activity


package com.example.shopcartdemo;import java.util.List;import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;import com.example.shopcartdemo.adapter.ShopCartAdapter;
import com.example.shopcartdemo.adapter.ShopCartAdapter.ViewCallback;
import com.example.shopcartdemo.presenter.MainPresenter;
import com.snicesoft.avlib.annotation.DataBind;
import com.snicesoft.avlib.annotation.DataType;
import com.snicesoft.avlib.annotation.Id;
import com.snicesoft.avlib.annotation.Layout;
import com.snicesoft.avlib.rule.IData;
import com.snicesoft.avlib.rule.IHolder;
import com.snicesoft.base.BaseActivity;@Layout(R.layout.activity_main)
public class MainActivity extendsBaseActivity<MainActivity.Holder, MainActivity.Data> implementsMainPresenter.Callback, ViewCallback {class Holder extends IHolder {@Id(R.id.lvShopCard)ListView lvShopCard;@Id(R.id.cbAll)CheckBox cbAll;@Id(R.id.tvPrice)TextView tvPrice;@Overridepublic void initViewParams() {cbAll.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {_data.shopCartAdapter.setAll(cbAll.isChecked());tvPrice.setText("¥" + _data.shopCartAdapter.calc());}});}}class Data extends IData {@DataBind(id = R.id.lvShopCard, dataType = DataType.ADAPTER)ShopCartAdapter shopCartAdapter = new ShopCartAdapter(getBaseContext());}@Overridepublic Holder newHolder() {return new Holder();}@Overridepublic Data newData() {return new Data();}MainPresenter presenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);presenter = new MainPresenter(this);presenter.setCallback(this);_data.shopCartAdapter.setCallback(this);}@Overrideprotected void onResume() {super.onResume();presenter.getShopCartList();}@Overridepublic void onClick(View v) {super.onClick(v);switch (v.getId()) {case R.id.btnGoPay:break;case R.id.btnDelete:break;default:break;}}boolean isNormal = true;@Overridepublic void setShopCartList(List<ShopCartAdapter.Data> list) {_data.shopCartAdapter.setDataList(list);refreshView();}@Overridepublic void refreshView() {_holder.cbAll.setChecked(_data.shopCartAdapter.isAll());_holder.tvPrice.setText("¥" + _data.shopCartAdapter.calc());}}

基本的Holder和Data将组件和数据进行简单的管理,清晰可见。
presenter将业务进行分离,将传统的activity中请求数据进行分离。
ViewCallback这个类是为了解决Adapter与Activity直接的交互定义的接口。

接下来看看Adapter


package com.example.shopcartdemo.adapter;import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;import com.example.shopcartdemo.R;
import com.snicesoft.avlib.AVLib;
import com.snicesoft.avlib.annotation.DataBind;
import com.snicesoft.avlib.annotation.DataType;
import com.snicesoft.avlib.annotation.Id;
import com.snicesoft.avlib.annotation.Layout;
import com.snicesoft.avlib.rule.IData;
import com.snicesoft.avlib.rule.IHolder;
import com.snicesoft.avlib.view.ViewFinder;
import com.snicesoft.avlib.widget.AvAdapter;@Layout(R.layout.item_shopcart)
public class ShopCartAdapter extendsAvAdapter<ShopCartAdapter.Holder, ShopCartAdapter.Data> {public ShopCartAdapter(Context context) {super(context);}class Holder extends IHolder {@Id(R.id.btnAdd)Button btnAdd;@Id(R.id.btnDelete)Button btnDelete;@Id(R.id.cbSelect)CheckBox cbSelect;@Id(R.id.img)ImageView img;@Overridepublic void initViewParams() {}}public static class Data extends IData {long gid;boolean isChecked = true;public long getGid() {return gid;}@DataBind(id = R.id.tvTitle)String title;@DataBind(id = R.id.tvPrice, prefix = "¥")int price;@DataBind(id = R.id.img, dataType = DataType.IMG)String image;@DataBind(id = R.id.edtCount)int count;public Data(long gid, String title, int price, String image, int count) {super();this.gid = gid;this.title = title;this.price = price;this.image = image;this.count = count;}}public interface ViewCallback {void refreshView();}ViewCallback callback;public void setCallback(ViewCallback callback) {this.callback = callback;}@Overridepublic Holder newHolder() {return new Holder();}@Overridepublic void bindAfter(int position, final View view, Holder holder,final Data data) {holder.cbSelect.setOnCheckedChangeListener(null);holder.cbSelect.setChecked(data.isChecked);holder.btnAdd.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {data.count++;AVLib.dataBindTo(data, new ViewFinder(view), "count");if (callback != null)callback.refreshView();}});holder.btnDelete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (data.count > 1) {data.count--;AVLib.dataBindTo(data, new ViewFinder(view), "count");if (callback != null)callback.refreshView();}}});holder.cbSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {data.isChecked = isChecked;if (callback != null)callback.refreshView();}});}public void setAll(boolean isChecked) {for (Data data : getDataList()) {data.isChecked = isChecked;}notifyDataSetChanged();}public int calc() {int total = 0;for (Data data : getDataList()) {if (data.isChecked)total += data.count * data.price;}return total;}public boolean isAll() {for (Data data : getDataList()) {if (!data.isChecked)return false;}return true;}
}

Holder的组件定义原则:需要在当前所在类中调用即可定义
Data的DataBind使用原则:需要绑定的的组件都可以。
当然通过上面可以看出Data中可以定义不用DataBind注解的字段,这个替代了传统的辅助Map或者List解决一些问题。
在上面的Data中用isChecked来表示CheckBox是否选中。这个问题,在我刚开始写android的时候,常常会用Map集合将position对应的boolean值记录下来,然后在getView中去检测。现在可以简单的通过Data几种管理,使得Adapter的字段不需要那么繁琐。

对于isChecked的使用产生了下面3个业务方法
setAll:这个方法用来设置全部选中(Activity中的全选按钮事件)
calc:这个方法用来计算购物车总额(Activity中的总计)
isAll:这个方法用来判断是否全部被选中(Activity的全选按钮设置checked的依据)

开发的思路就到这里,代码比较简单,下面送上源码。

点击下载源码

Android快速开发之appBase——实战《购物车》相关推荐

  1. Android快速开发之appBase——(6).HttpReq和APICloudSDK

    转载请注明本文出自JFlex的博客http://blog.csdn.net/jflex/article/details/46462077,请尊重他人的辛勤劳动成果,谢谢! Android快速开发之ap ...

  2. Android快速开发之appBase——(4).详解com.snicesoft.Application和BaseActivity

    转载请注明本文出自JFlex的博客http://blog.csdn.net/jflex/article/details/46441571,请尊重他人的辛勤劳动成果,谢谢! Android快速开发之ap ...

  3. Android快速开发之appBase——(5).BasePresenter的使用

    转载请注明本文出自JFlex的博客http://blog.csdn.net/jflex/article/details/46456621,请尊重他人的辛勤劳动成果,谢谢! Android快速开发之ap ...

  4. android idata 模式,Android快速开发之appBase——(3).详解IHolder和IData

    Android快速开发之appBase--(3).详解IHolder和IData IHolder和IData是AVLib的两个组件,在前面已经使用过了,那么这一篇将会详细说明这两个组件的用法. IHo ...

  5. Java服务器接口快速开发之Servlet详细教程

    今日科技快讯 7月14日晚间消息,据乐视网刚刚披露的业绩预告,公司预计2017年上半年亏损6.37亿至6.42亿元,上年同期盈利2.84亿元.报告期内,乐视网资产减值损失计提规模较大约为2.3亿元,其 ...

  6. Android NDK开发之 NEON基础介绍

    原文:http://blog.csdn.net/app_12062011/article/details/50434259 Android NDK开发之 NEON基础介绍 这是官方介绍: http:/ ...

  7. 【转载】Android逆向开发之smali语言的学习

    Android逆向开发之smali语言的学习 该文转载自乱码三千 – 分享实用IT技术 smali和java基本数据类型对比 smali java B byte S short I int J lon ...

  8. android程序移动到Linux,Android应用开发之Android 系统 -- 使用Xshell在Windows系统和Linux系统之间进行文件传输...

    本文将带你了解Android应用开发之Android 系统 -- 使用Xshell在Windows系统和Linux系统之间进行文件传输,希望本文对大家学Android有所帮助. 使用Xshell在Wi ...

  9. 镜像处理坐标 android,Android应用开发之Android重写ImageView实现图片镜像效果的代码教程...

    本文将带你了解Android应用开发之Android重写ImageView实现图片镜像效果的代码教程,希望本文对大家学Android有所帮助. 前两天朋友问我一个问题,如何实现从手机系统相册加载一张图 ...

  10. Android NDK开发之旅31 FFmpeg音频解码

    ###前言 #####基于Android NDK开发之旅30--FFmpeg视频播放这篇文章,我们已经学会视频解码基本过程.这篇文章就对音频解码进行分析. #####音频解码和视频解码的套路基本是一样 ...

最新文章

  1. 一篇文看懂Hadoop
  2. html表单全选框,form表单里如何实现全选和全不选
  3. 机器人焊枪动作与编程实验_机器人编程实验报告.pdf
  4. iphone7wifi模块多少钱_模块炉价格参差不齐,消费者应独具慧眼!
  5. apache 和 nginx 301重定向配置方法
  6. 装上后这 14 个插件后,PyCharm 能飞起
  7. 无法设置html过渡效果,html – CSS3过渡显示无阻止过度滚动
  8. 互联网日报 | 3月7日 星期日 | 《你好,李焕英》成中国影史票房亚军;丰巢新增智能存包柜业务;特斯拉推出内部社交平台...
  9. Photoshop cs6中kuler和mini bridge打开是空白的解决方法
  10. notes java api_如何使用Java来调用Notes API发送邮件(包括附件)
  11. java毕业设计——基于java+jsp+Tomcat的电子书下载系统设计与实现(毕业论文+程序源码)——电子书下载系统
  12. 制定自动化测试实施计划
  13. 兄弟們,彈鋼琴不是只有有錢人可以玩的
  14. 对于文件编码格式的浅显理解
  15. 虚幻AI蓝图基础笔记(万字整理)
  16. 「MacTeX」如何插入代码块
  17. 中国第一批程序员的“青春饭”已经恰完了,35+的程序员该何去何从?
  18. 如我提升自我学习能力
  19. HNUST-OJ-1803二叉树遍历1
  20. linux新建磁盘分区

热门文章

  1. noip2018翻车记
  2. java delight 咖啡是什么意思_各种咖啡的含义是什么?
  3. 2017CS231n李飞飞深度视觉识别笔记(二)——图像分类
  4. 旭阳集团锚定“2025” 企业卓越运营让信息化来帮忙
  5. 100个python算法超详细讲解:将真分数分解为埃及分数
  6. 【弄nèng - Skywalking】入门篇(一)—— Skywalking安装与使用
  7. 小学校计算机教室年度工作总结,小学计算机教师年度工作总结
  8. openstack资料-陈沙克整理
  9. 自动收取蚂蚁森林能量雨
  10. 个人电子邮箱怎么注册?