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的依据)

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

点击下载源码

6 1
原创粉丝点击