Android设计模式——MVP

一、什么是MVP

MVP:全称 Model-View-Presenter。

MVP框架由3部分组成:View层负责显示,Presenter层负责逻辑处理,Model层提供数据。

View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity,Fragment)

Model:负责存储、检索、操纵数据

Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

二、创建Model Presenter View三个包

三、代码编写

1.View层代码

view层负责界面操作,如何确定view层里面有那些操作呢?
拿我这个UserView举例.
onLogin代表登录时候要做的事情,比如显示一个进度dialog
loginSuccess代表登录成功后要做的事情,做界面跳转等操作
loginFail表示登录失败后得操作,显示一个Toast等

public interface  UserView{
    void onLogin();
    void loginSuccess(UserBean bean);
    void loginFail(Exception e,int code);
}

2.Presenter层代码

这层主要负责View层和Model层的连接,也有中间人得意思,
View层请求Presenter层,Presenter在请求Model层,Model层处理数据之后通过回调接口传递给Presenter层,Presenter在传递给View层

在上一张图

public class UserPresenter implements UserCallback {
    private UserView  mUserView;
    private UserModel mModel;

    public UserPresenter(UserView baseView) {
        mUserView = baseView;
        mModel= new UserModel(this);
    }

    public void userLogin(String name, String pass){
        mUserView.onLogin();
        mModel.userLogin(name,pass);
    }

    @Override
    public void onSuccess(UserBean bean) {
        mUserView.loginSuccess(bean);
    }

    @Override
    public void onFail(Exception e, int code) {
        mUserView.loginFail(e,code);

    }
}
public  interface  UserCallback {
    void onSuccess(UserBean bean);
    void onFail(Exception e ,int code);
}

3.model层代码

model层进行网络请求等耗时任务处理,model会留有一个回调地址,当数据处理完成之后回调它,在本实例中UserCallback就是一个回调接口,具体实现类在Presenter层,也就是说数据处理完成之后会传递给Presenter层

public class UserModel {
    private UserCallback mUserCallback;
    private Map<String,String> mUserMaps;
    private Handler mHandler;

    /**
     *
     * @param userCallback 回调地址,当数据处理完成之后调用这个接口
     */
    public UserModel(UserCallback userCallback) {
        mUserCallback = userCallback;
        mUserMaps=new HashMap<>();
        mHandler =new Handler(Looper.getMainLooper());
        mUserMaps.put("user1","123456");
        mUserMaps.put("user2","12345");
        mUserMaps.put("user3","1234");

    }

    public void userLogin(final  String name, final String pass){
        /**
         * 模拟延时操作,2秒后调用UserCallback接口,回传数据
         */
       mHandler.postDelayed(new Runnable() {
           @Override
           public void run() {
               if (mUserMaps.containsKey(name) && mUserMaps.get(name).equals(pass)){
                   UserBean bean =new UserBean(name,pass,20);
                   mUserCallback.onSuccess(bean);
               }else {
                   Exception exception =new Exception("用户名或账号错误");
                   mUserCallback.onFail(exception,400);
               }
           }
       },2000);
    }

}

4.MainActivity

public class MainActivity extends AppCompatActivity implements UserView ,View.OnClickListener {
    private  ProgressDialog mProgressDialog;
    private EditText mUserText;
    private EditText mUserPass;
    private Button mLoginBtn;
    private UserPresenter mUserPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUserPresenter=new UserPresenter(this);
        initView();
        initEvents();
    }

    private void initEvents() {
        mLoginBtn.setOnClickListener(this);
    }

    public void initView () {
        mUserText = (EditText) findViewById(R.id.userName);
        mUserPass = (EditText) findViewById(R.id.userPass);
        mLoginBtn = (Button) findViewById(R.id.loginBtn);
    }

    @Override
    public void onLogin() {
        mProgressDialog =new ProgressDialog(this);
        mProgressDialog.show();
    }

    @Override
    public void loginSuccess(UserBean bean) {
        Toast.makeText(this, "登录成功,年龄"+bean.getAge(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void loginFail(Exception e, int code) {
        if (mProgressDialog!=null){
            mProgressDialog.dismiss();
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.loginBtn:
                if (getUserPass().length()==0 || getUserText().length()==0){
                    Toast.makeText(this, "请输入账号或密码", Toast.LENGTH_SHORT).show();
                    return;
                }
                mUserPresenter.userLogin(getUserText(),getUserPass());
                break;
        }
    }
    private String getUserText(){
        return mUserText.getText().toString();
    }
    private String getUserPass(){
        return  mUserPass.getText().toString();
    }
}

5.XML布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:background="#ffffff"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_margin="15dp"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:paddingLeft="6dp"
            android:paddingRight="6dp"
            android:textColor="#616161"
            android:id="@+id/userName"
            android:inputType="text"
            android:background="@drawable/shape_editview"
            android:layout_width="match_parent"
            android:layout_height="55dp" />
        <EditText
            android:paddingLeft="6dp"
            android:paddingRight="6dp"
            android:textColor="#616161"
            android:layout_marginTop="8dp"
            android:id="@+id/userPass"
            android:inputType="textPassword"
            android:background="@drawable/shape_editview"
            android:layout_width="match_parent"
            android:layout_height="55dp" />
        <Button

            android:layout_marginTop="8dp"
            android:textColor="#ffffff"
            android:textSize="19sp"
            android:background="@drawable/shape_login_btn"
            android:text="登录"
            android:id="@+id/loginBtn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>

6.两个shape
shape_editview.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="30dp"></corners>
    <solid android:color="#f7f5f5"></solid>
</shape>

shape_login_btn.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <corners android:radius="100dp"></corners>
            <solid android:color="#03a9f4"></solid>
        </shape>
    </item>
    <item android:state_pressed="false">
        <shape>
            <corners android:radius="100dp"></corners>
            <solid android:color="#0a9ddf"></solid>
        </shape>
    </item>
</selector>

以上就是MVP模式得简单实现.一定要多加练习,才能体会掉MVP得优点

原文地址:https://www.cnblogs.com/HouXinLin/p/10828094.html

时间: 2024-08-03 18:16:11

Android设计模式——MVP的相关文章

Android设计模式-MVP模式

一.什么是MVP模式 MVP(Model / View / Presenter)  是从经典的模式MVC演变而来,Presenter代替activity和fragment成为控制器,而activity和fragment专心做View层该做的事. 二.MVP的优点 1.模型和视图分离开了,层次更清晰了. 2.Presenter可以重复利用了. 3.如果我们把逻辑放在Presenter中,单元测试更简单了 三.实战 下边是我项目的结构图 MVP中parsenter处理完逻辑后通过接口通知View层,

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与工厂方法模式和抽象工厂模式不同,后两者的目的是为了实现多态性,而 Builder 模式的目的则是为了将对象的构建与展示分离.Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.一个复杂的对象有大量的组成部分,比如汽车它有车轮.方向盘.发动机.以及各种各样的小零件,要将这些部件装配成一辆汽车,这个装配过

java/android 设计模式学习笔记(一)---单例模式

前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使用的时候也会有一些坑. PS:对技术感兴趣的同鞋加群544645972一起交流 设计模式总目录 java/android 设计模式学习笔记目录 特点 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的使用很广泛,比如:线程池(threadpool).缓存(cache).对

java/android 设计模式学习笔记(7)---装饰者模式

这篇将会介绍装饰者模式(Decorator Pattern),装饰者模式也称为包装模式(Wrapper Pattern),结构型模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一,但比继承更加灵活.在现实生活中也可以看到很多装饰者模式的例子,或者可以大胆的说装饰者模式无处不在,就拿一件东西来说,可以给它披上无数层不一样的外壳,但是这件东西还是这件东西,外壳不过是用来扩展这个东西的功能而已,这就是装饰者模式,装饰者的这个角色也许各不相同但是被装饰的对

java/android 设计模式学习笔记(13)---享元模式

这篇我们来介绍一下享元模式(Flyweight Pattern),Flyweight 代表轻量级的意思,享元模式是对象池的一种实现.享元模式用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,缓存可共享的对象,来达到对象共享和避免创建过多对象的效果,这样一来就可以提升性能,避免内存移除和频繁 GC 等. 享元模式的一个经典使用案例是文本系统中图形显示所用的数据结构,一个文本系统能够显示的字符种类就是那么几十上百个,那么就定义这么些基础字符对象,存储每个字符的显示外形和其他的格式化数据

Android 设计模式-单例模式

Android 设计模式-单例模式 什么情况下需要单例模式? 一些类提供公共功能供别人调用,本身不会处理业务逻辑 类会被许多类和线程调用 设计单例模式 public class Singleton{ private static Singleton mSingleton; private Singleton(){ } public static Singleton getInstance(){ if(mSingleton == null){ mSingleton = new Singleton(

java/android 设计模式学习笔记(12)---组合模式

这篇我们来介绍一下组合模式(Composite Pattern),它也称为部分整体模式(Part-Whole Pattern),结构型模式之一.组合模式比较简单,它将一组相似的对象看作一个对象处理,并根据一个树状结构来组合对象,然后提供一个统一的方法去访问相应的对象,以此忽略掉对象与对象集合之间的差别.这个最典型的例子就是数据结构中的树了,如果一个节点有子节点,那么它就是枝干节点,如果没有子节点,那么它就是叶子节点,那么怎么把枝干节点和叶子节点统一当作一种对象处理呢?这就需要用到组合模式了. 转

java/android 设计模式学习笔记(9)---代理模式

这篇博客我们来介绍一下代理模式(Proxy Pattern),代理模式也成为委托模式,是一个非常重要的设计模式,不少设计模式也都会有代理模式的影子.代理在我们日常生活中也很常见,比如上网时连接的代理服务器地址,更比如我们平时租房子,将找房子的过程代理给中介等等,都是代理模式在日常生活中的使用例子. 代理模式中的代理对象能够连接任何事物:一个网络连接,一个占用很多内存的大对象,一个文件,或者是一些复制起来代价很高甚至根本不可能复制的一些资源.总之,代理是一个由客户端调用去访问幕后真正服务的包装对象