1.MVC架构模式
View:对应的xml布局文件
Model:实体模型(JavaBean)
Controllor:对应于Activity业务逻辑,数据处理和UI处理
该模式的特点,就是当某个界面非常复杂的时候,activity代码量会上千行的增加,非常冗余。
2.MVP架构模式
View:对应的xml布局文件
Model:实体模型(JavaBean)
Presenter:责完成View于Model间的交互和业务逻辑
搭建MVP的一个栗子
(1).创建一个持有View接口的基类的BasePersenter
public class BasePersenter<T> implements Persenter<T> {
protected T mView;//View接口
protected WebService mRetrofit = MyRertofit.getLoginService().create(WebService.class);
protected CompositeSubscription mCompositeSubscription;
public BasePersenter(T t) {
attachView(t);
}
@Override
public void attachView(T view) {
this.mView = view;
}
@Override
public void detachView() {
this.mView = null;
onUnsubscribe();
}
public void onUnsubscribe() {
if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.unsubscribe();
}
}
/***
* 通用的网络请求的方法
* @param observable
* @param subscriber
*/
public void addSubscription(Observable observable, Subscriber subscriber) {
if (mCompositeSubscription == null) {
mCompositeSubscription = new CompositeSubscription();
}
if (!NetworkUtils.isConnected()) {
ToastUtils.showShort("网络不可用,请检查网络~");
}
mCompositeSubscription.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber));
}
}
(2).新建一个继承BasePersenter的PayCarPersenter
public class PayCarPersenter extends BasePersenter<PayCarView>{
public PayCarPersenter(PayCarView baseResultBaseView) {
super(baseResultBaseView);
}
public void getDetail(String rechargeAmount,String giftAmount){
mView.OnGetPayInfoLoading();
HashMap<String, String> map = new HashMap();
map.put("userId", SharedPreferencesUtils.getString(App.application, Constans.USER_ID, ""));
map.put("rechargeAmount",rechargeAmount);
map.put("giftAmount",giftAmount);
map.put("terminal","1");
addSubscription(mRetrofit.recharge(map),new SubscriberCallBack<>(new ApiCallback<BaseResult<PayCarBean>>() {
@Override
public void onSuccess(BaseResult<PayCarBean> payCarBeanBaseResult) {
if (payCarBeanBaseResult.getSuccess()){
mView.OnGetPayInfoSuccess(payCarBeanBaseResult.getResultObject());
}else{
mView.OnGetPayInfoError("获取充值信息失败,请重试~");
}
}
@Override
public void onFailure(int code, String msg) {
mView.OnGetPayInfoError("获取充值信息失败,请重试~");
}
@Override
public void onCompleted() {
mView.OnGetPayInfoComplete();
}
}));
}
public void toPay(String orderId){
mView.OnToPayLoading();
HashMap<String, String> map = new HashMap();
map.put("orderNumber", orderId);
map.put("payType","11");
map.put("ip", NetworkUtils.getIPAddress(true));
map.put("orderType","recharge");
map.put("payWay","4");
map.put("isRaw","1");
addSubscription(mRetrofit.getzxPlay(map),new SubscriberCallBack<>(new ApiCallback<BaseResult<Object>>() {
@Override
public void onSuccess(BaseResult<Object> stringBaseResult) {
if (stringBaseResult.getSuccess()){
mView.OnToPaySuccess(stringBaseResult.getResultObject());
}else{
mView.OnToPayError("获取支付信息失败,请重试~");
}
}
@Override
public void onFailure(int code, String msg) {
mView.OnToPayError("获取支付信息失败,请重试~");
}
@Override
public void onCompleted() {
mView.OnToPayComplete();
}
}));
}
}
(3).PayCarView 接口
public interface PayCarView {
void OnGetPayInfoSuccess(PayCarBean bean);
void OnGetPayInfoError(String msg);
void OnGetPayInfoComplete();
void OnGetPayInfoLoading();
void OnToPaySuccess(Object bean);
void OnToPayError(String msg);
void OnToPayComplete();
void OnToPayLoading();
}
(4).新建一个持有presenter基类MvpActivity或者MvpFragment
public abstract class MvpActivity<P extends BasePersenter> extends BaseActivity {
protected P mPersenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mPersenter = createPersenter();
super.onCreate(savedInstanceState);
}
protected abstract P createPersenter();
@Override
protected void onDestroy() {
super.onDestroy();
if (mPersenter != null)
mPersenter.detachView();
}
}
(5).新建一个继承自MvpActivity的子Activity,实现抽象方法createPersenter()
public class PayCarActivity extends MvpActivity<PayCarPersenter> implements PayCarView {
@BindView(R.id.tv_zhensong)
TextView tv_zhensong;
@BindView(R.id.tv_shij)
TextView tv_shij;
@BindView(R.id.tv_money)
TextView tv_money;
@BindView(R.id.tv_order_id)
TextView tv_order_id;
private IWXAPI api;
@Override
protected PayCarPersenter createPersenter() {
return new PayCarPersenter(this);
}
@Override
protected void onError() {
initData();
}
@Override
protected void onBack() {
showGiveUpPayDialog();
}
@Override
protected int setRootView() {
return R.layout.activity_pay_cart;
}
@Override
protected void initData() {
mPersenter.getDetail(getStringExtra("money"), getStringExtra("disMoney"));
}
/***
* 放弃支付提示框
*/
private void showGiveUpPayDialog() {
DialogUtils.showDialog(this, "提示", "确定放弃充值?使用会员卡储值,\n立享更多优惠哦?", maAlertDialog -> {
maAlertDialog.dismiss();
finish();
});
}
@Override
protected void initToolBar() {
setTitle("确认支付");
}
@Override
protected void initView(Bundle savedInstanceState) {
api = WXAPIFactory.createWXAPI(this, Constans.APP_ID);
}
@OnClick(R.id.ll_wx_pay)
public void toPay() {
if (api.isWXAppInstalled()) {
//检测当前微信版本是否支持微信支付
boolean isPaySupported = api.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
if (isPaySupported) {
mPersenter.toPay(tv_order_id.getText().toString());
} else {
ToastUtils.showLong("您当前的微信版本过低,不支持微信支付");
}
} else {
ToastUtils.showLong("您没有安装微信,请您安装后再支付");
}
}
@Override
public void OnGetPayInfoSuccess(PayCarBean bean) {
tv_money.setText(bean.getRechargeAmount() + "");
tv_order_id.setText(bean.getOrderId());
tv_shij.setText(bean.getRealAmount() + "元");
tv_zhensong.setText(bean.getGiftAmount() + "元");
overLoading();
}
@Override
public void OnGetPayInfoError(String msg) {
showToast(msg);
showError();
}
@Override
public void OnGetPayInfoComplete() {
}
@Override
public void OnGetPayInfoLoading() {
toLoading();
}
@Override
public void OnToPaySuccess(Object bean) {
App.rechargeMoney = tv_money.getText().toString().trim();
JSONObject jsonObject = null;
JSONObject json = null;
try {
jsonObject = new JSONObject(bean.toString());
json = jsonObject.optJSONObject("pay_info");
PayReq req = new PayReq();
req.appId = json.optString("appid");
req.partnerId = json.optString("partnerid");
req.prepayId = json.optString("prepayid");
req.nonceStr = json.optString("noncestr");
req.timeStamp = json.optString("timestamp");
req.packageValue = json.optString("package");
req.sign = json.optString("sign");
req.extData = "app data";
Constans.payFrom = 3;
api.sendReq(req);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void OnToPayError(String msg) {
showToast(msg);
}
@Override
public void OnToPayComplete() {
closeLoading();
}
@Override
public void OnToPayLoading() {
showLoadding("正在获取支付信息~");
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
showGiveUpPayDialog();
}
return false;
}
@Subscribe
public void toWebWxPay(WebPayEvent webPayEvent) {
switch (webPayEvent.getVar()) {
case 0:
startActivity(RechargeSuccessActivity.class);
AppManager.getAppManager().finishActivity(StoreValueCardActivity.class);
finish();
break;
default:
DialogUtils.showNoCancleDialog(PayCarActivity.this, "支付说明", "用户支付失败或取消支付", maAlertDialog -> {
maAlertDialog.dismiss();
});
break;
}
}
}
核心就是Activity实现View的接口,并持有Presenter对象,Presenter中持有Model和View对象,负责完成View于Model间的交互和业务逻辑,本文中的Prsenter并没有Model,而是直接新建了一些类似model中的请求方法,这样可以省掉Model接口和ModelIml接口实现类,简化代码。
3.MVVM架构
View:对应的xml布局文件
Model:实体模型(JavaBean)
ViewModel:责完成View于Model间的交互和业务逻辑(依赖于Google的Databing框架)
MVVM的目标和思想MVP类似,利用数据绑定(Data Binding)、依赖属性(Dependency Property)等新特性,打造了一个更加灵活高效的架构。
(1)######DataBing框架的使用(https://www.jianshu.com/p/d429174b8d07)
ObservableField 以及它的派生 ObservableBoolean、 ObservableByte ObservableChar、ObservableShort、ObservableInt、ObservableLong、ObservableFloat、ObservableDouble、 ObservableParcelable 支持双向绑定,只要数据变了,xml文件中的数据会自动刷新。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="doubleBindBean"
type="com.zx.databindingdemo.bean.DoubleBindBean" />
<variable
name="doubleBindBean2"
type="com.zx.databindingdemo.bean.DoubleBindBean2" />
<variable
name="list"
type="android.databinding.ObservableArrayList<String>" />
<variable
name="map"
type="android.databinding.ObservableArrayMap<String,Object>" />
<variable
name="onClickListener"
type="android.view.View.OnClickListener" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{doubleBindBean.content}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{doubleBindBean2.username}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{list[0]}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{map["key0"]}' />
<Button
android:id="@+id/change_content_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{onClickListener}"
android:textAllCaps="false"
android:text="BaseObservable方式改变内容" />
<Button
android:id="@+id/change_content_btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{onClickListener}"
android:textAllCaps="false"
android:text="ObservableFields方式改变内容" />
<Button
android:id="@+id/change_content_btn3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{onClickListener}"
android:textAllCaps="false"
android:text="list改变内容" />
<Button
android:id="@+id/change_content_btn4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{onClickListener}"
android:textAllCaps="false"
android:text="map改变内容" />
</LinearLayout>
</layout>
public class DoubleBindBean2 {
//变量需要为public
public final ObservableField<String> username = new ObservableField<>();
}
public class DoubleBindActivity extends AppCompatActivity implements View.OnClickListener {
private DoubleBindBean2 doubleBindBean2;
private boolean flag2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityDoubleBindBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_double_bind);
doubleBindBean2 = new DoubleBindBean2();
doubleBindBean2.username.set("我是原始内容2");
binding.setDoubleBindBean2(doubleBindBean2);
binding.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.change_content_btn2:
//ObservableFields
flag2 = !flag2;
if (flag2) {
doubleBindBean2.username.set("我是更新后的内容2");
} else {
doubleBindBean2.username.set("我是原始内容2");
}
break;
}
}
}
(2).基于DataBinding框架,搭建MVVM框架,和MVP类似
A:新建一个ViewModel的类似Presenter的类,持有bing对象,或着adapter对象,然后ViewModel中做网络请求,和然后通过bind.setBean()进行数据刷新即可,不需要回调到Activity中进行处理,直接在ViewModel中就完成了数据的更新。
B:Activity中持有ViewModel的对象,通过该对象,调用内部网络请求等各种方法。
网友评论