【第22期】观点:IT 行业加班,到底有没有价值?

android MVP设计模式实践

原创 2015年11月20日 17:05:31

android MVP设计模式实践

用MVP模式实现一个买花的example,MVP对应(Model-View-Presenter),先写下一个接口用与Presenter->View沟通。

package com.aniu.mvpexample.app.buy_flower;

interface IBuyFlowerView {
    //负责ui 进度 、提示、跳转提供操作接口
    public void showProgress();
    public void hideProgress();
    public void nevigateToHome();
    public void buyError();
    public void buySuccess();

}

从方法名上可以看得出来,Presenter<->View之间的交互主要就是Presenter<->Model之间操作结果的一些回调,把操作的结果告诉activity,然后activity就负责ui 的显示和跳转就好了。

package com.aniu.mvpexample.app.buy_flower;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.aniu.mvpexample.app.R;

public class BuyFlowerActivity extends Activity implements IBuyFlowerView, View.OnClickListener{

    private  EditText buy_et_num;
    private  ProgressBar buy_progress;
    private  TextView buy_tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buy_flower);
        findViewById(R.id.buy_btn).setOnClickListener(this);
        buy_et_num = (EditText) findViewById(R.id.buy_et_num);
        buy_progress = (ProgressBar) findViewById(R.id.buy_progress);
        buy_tv = (TextView)findViewById(R.id.buy_tv);


    }

    @Override
    public void showProgress() {
        buy_progress.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        buy_progress.setVisibility(View.GONE);

    }

    @Override
    public void nevigateToHome() {

    }

    @Override
    public void buyError() {

    }

    @Override
    public void buySuccess() {

    }
    @Override
    public void onClick(View v) {

    }
}

OK,activity就去实现上面的接口,看到ProgressBar是否显示是由Presenter来回调控制的。顺便给button设置一下点击事件。
activity_buy_flower.xml布局示图:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <EditText
            android:id="@+id/buy_et_num"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/buy_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="buy"/>
        <TextView
            android:id="@+id/buy_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    </LinearLayout>

    <ProgressBar
        android:id="@+id/buy_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone"
        />

</FrameLayout>

接下来看看Presenter是怎么跟Model交互完了以后去告诉activity更新ui的。
先定义一个接口,这个接口主要就是View-> Presenter->Model,意思就是通过ui(View) 的操作,然后通过Presenter 递交给Model处理。

package com.aniu.mvpexample.app.buy_flower;

interface IBuyFlowerPresenter {

    public void buyFlower(int num);
    public int getFlowerNum();

}

OK,界面想要操作的就是买花、获取花的数量。
接着去实现它。

package com.aniu.mvpexample.app.buy_flower;

public class IBuyFlowerPresenterImpl implements IBuyFlowerPresenter {

    private IBuyFlowerView buyFlowerView;

    public IBuyFlowerPresenterImpl(IBuyFlowerView buyFlowerView){
        this.buyFlowerView = buyFlowerView;
    }


    @Override
    public void buyFlower(int num) {
        //买的时候显示进度
        buyFlowerView.showProgress();

        //...此处递交给model层处理数据

    }

    @Override
    public int getFlowerNum() {
        //..此处递交给model层处理数据,然后返回数量
        return 0;
    }
}

可以看到,Presenter层负责的就是告诉model什么时候处理数据,同时也告诉View什么时候更新。即:View<- Presenter ->model

OK,接下来把Model层的接上。

package com.aniu.mvpexample.app.buy_flower;

public interface IBuyFlowerInteractor {

    public void buyFlower(int num);

    public int getFlowerNum();
}

跟上面的IBuyFlowerPresenter方法一样,一层一层的传到model层去处理。
实现:

package com.aniu.mvpexample.app.buy_flower;

public class IBuyFlowerInteractorImpl implements IBuyFlowerInteractor {
    private int num = 100;//我是从网络获取的
    @Override
    public void buyFlower(int num) {
        this.num -= num;
    }

    @Override
    public int getFlowerNum() {
        return num;
    }
}

简单模拟一下买花的逻辑,然后把View Presenter Model 组装一下。
首先是activity中得使用Presenter传递业务。

public class BuyFlowerActivity extends Activity implements IBuyFlowerView, View.OnClickListener {

    private  EditText buy_et_num;
    private  ProgressBar buy_progress;
    private  IBuyFlowerPresenter buyFlowerPresenter;
    private  TextView buy_tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buy_flower);
        //...省略一堆findViewById
        buyFlowerPresenter = new IBuyFlowerPresenterImpl(this);
    }
    //....省略部分代码
    @Override
    public void onClick(View v) {

        String num = buy_et_num.getText().toString();
        int numInt =Integer.valueOf(num);
        //需要买的数量
        buyFlowerPresenter.buyFlower(numInt);
        //显示剩下的数量
        buy_tv.setText(buyFlowerPresenter.getFlowerNum() + "");
    }
}

Presenter中把View需求传递给Model,修改代码:

package com.aniu.mvpexample.app.buy_flower;

/**
 * Created by aniu on 15/11/19.
 */
public class IBuyFlowerPresenterImpl implements IBuyFlowerPresenter {

    private IBuyFlowerView buyFlowerView;
    private IBuyFlowerInteractor buyFlowerInteractor;

    public IBuyFlowerPresenterImpl(IBuyFlowerView buyFlowerView){
        this.buyFlowerView = buyFlowerView;
        buyFlowerInteractor = new IBuyFlowerInteractorImpl();
    }

    @Override
    public void buyFlower(int num) {
        //买的时候显示进度
        buyFlowerView.showProgress();

        //...此处递交给model层处理数据
        buyFlowerInteractor.buyFlower(num);

    }
    @Override
    public int getFlowerNum() {
        //..此处递交给model层处理数据,然后返回数量
        return buyFlowerInteractor.getFlowerNum();
    }

结果是这样的,数能正常获取,ProgressBar能转。

结果

一个简单的栗子基本能看懂MVP了。

Presenter作为View 和 Model的中间层,主要起到一个很好的衔接作用。

  • View->Presenter :View层到Presenter层主要也就是将用户操作界面后产生的需求传递给Presenter。具体数据怎么来的View真不需要管。
  • Presenter->Model:Presenter拿到了View的需求了以后,就跟Model层说,Model哥们,我要买5朵花,然后Model哥就一系列网络请求、缓存数据、等。
  • Model->Presenter:Model处理数据的时候不管是失败还是成功都会告诉Presenter一个结果。
  • Presenter->View:所以Presenter拿到结果了以后就去告诉View,然后View就根据结果是成功还是失败来显示界面。

    那么这张图就很容易的理解了:
    这里写图片描述

MVP优势:
分层带来的就是复用性强、易调试(易调试bug就少有木有)、还有很直观的就是别都堆在activity里了有木有。
MVP缺点:
就写个简单的功能蹦出这么多个类来。。。
这里写图片描述

完整的栗子:
https://github.com/linchangjian/android_aniu_mvp
参考:
https://github.com/konmik/konmik.github.io/wiki/Introduction-to-Model-View-Presenter-on-Android
https://github.com/antoniolg/androidmvp

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

浅谈Android MVP设计模式(简单结合RxJava+Retrofit)

什么是MVP 为什么要用MVP 怎么去完成一个MVP的设计呢 demo实例功能虽小五脏俱全 准备工作 View的基类 presenter的基类 Model的基类 具体的业务实现 转载请指明出处:htt...

设计模式-责任链(Chain Of Responsibility)-实践篇

看了一些设计模式的书籍和文章,结合先前做过的一个真实的项目,对责任链模式作个小结 1.项目需求和背景 先前做过一个人力资源管理的产品,产品中有部分功能就是要实现员工请假审批流程,员工提交请假申请比较简单,无非就是填写一些请假单的基本信息,如请假的起至日期,请假类型(年假,病假),...
  • jgsj
  • jgsj
  • 2011-01-26 14:41
  • 38

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

Android Mvp设计模式结合RxJava+OkHttp+retrofit浅谈

前一段时间撸了好久的webview和前端的代码,停下来时间感觉要学点什么东西,在此和大家分享下我对mvp设计模式的理解,可能很多小伙伴项目中也会用到。先上代码,后面附上个人总结。View层/** *...

互联网专家资源分享(二)

1.  换位思考  沈阳 前台页面处理,利用CSS和DIV构建页面。面向在校毕业生或者刚参加工作人员 div+css页面处理html控件解析,数据处理,sql语句构造 2.  moosefs调优  济南<
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)