Android快速开发之appBase——实战《购物车》
来源:互联网 发布:赌博官网php源码 编辑:程序博客网 时间:2024/05/22 12:56
转载请注明本文出自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"; @Override public 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> extends BasePresenter<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() { @Override public 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); } @Override public 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 extends BaseActivity<MainActivity.Holder, MainActivity.Data> implements MainPresenter.Callback, ViewCallback { class Holder extends IHolder { @Id(R.id.lvShopCard) ListView lvShopCard; @Id(R.id.cbAll) CheckBox cbAll; @Id(R.id.tvPrice) TextView tvPrice; @Override public void initViewParams() { cbAll.setOnClickListener(new OnClickListener() { @Override public 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()); } @Override public Holder newHolder() { return new Holder(); } @Override public Data newData() { return new Data(); } MainPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = new MainPresenter(this); presenter.setCallback(this); _data.shopCartAdapter.setCallback(this); } @Override protected void onResume() { super.onResume(); presenter.getShopCartList(); } @Override public 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; @Override public void setShopCartList(List<ShopCartAdapter.Data> list) { _data.shopCartAdapter.setDataList(list); refreshView(); } @Override public 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 extends AvAdapter<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; @Override public 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; } @Override public Holder newHolder() { return new Holder(); } @Override public 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() { @Override public void onClick(View v) { data.count++; AVLib.dataBindTo(data, new ViewFinder(view), "count"); if (callback != null) callback.refreshView(); } }); holder.btnDelete.setOnClickListener(new OnClickListener() { @Override public 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() { @Override public 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——实战《购物车》
- Android快速开发之appBase——(1).appBase介绍
- Android快速开发之appBase——(2).万能的Adapter
- Android快速开发之appBase——(3).详解IHolder和IData
- Android快速开发之appBase——(4).详解com.snicesoft.Application和BaseActivity
- Android快速开发之appBase——(5).BasePresenter的使用
- Android快速开发之appBase——(6).HttpReq和APICloudSDK
- 快速开发Android购物车项目
- 实战J2EE—开发购物网站(一)
- 实战J2EE—开发购物网站(二)
- 实战J2EE—开发购物网站(三)
- 实战J2EE—开发购物网站(四)
- 购物车设计开发之二 —— 业务建模
- 购物车设计开发之二 —— 业务建模
- 微信小程序之购物车 —— 微信小程序实战商城系列(5)
- Android——自定义View之购物车的加减
- React Native实战系列第十四篇——购物车
- ASP.NET开发购物推车之购物车类
- 面试题12:打印1到最大的n位数
- Android 中IO 操作数据总结
- cocos2d-js中使用cocostudio中的帧动画
- 中国上网费问题
- 北京在哪里捐献肾可以有偿多少钱
- Android快速开发之appBase——实战《购物车》
- 11111111111111111111111111
- 单词学习-长久的过程
- HDU5246 超级赛亚ACMer
- hdu 1548 A strange lift
- ubutnu12.10安装xen4.2.1以及remus和DRBD
- ubuntu14.04安装cuda 7.0出错
- 安卓小技巧--项目总结(二)
- codeforces 553D Nudist Beach 二分+bfs