MVP登陆模块


在MVP模式里通常包含4个要素:
(1) View :负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2 ) View interface :需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3) Model :负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4) Presenter :作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

二、为什么使用MVP模式
在Android开发中,Activity并不是一个标准的MVC模式中的Controller, 它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理).
另外,回想一下你在开发Android应用时是如何对代码逻辑进行单元测试的?是否每次都要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试?然而由于Android平台的特性,每次部署都耗费了大量的时间,这直接导致开发效率的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明了什么?说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。
好了上代码Mvp的登陆模块

首先是View层
定义一个View的interface
public interface Iview {
    /**
     * 登录成功
     */
    void onLoginSuccess();

    /**
     * 登录失败
     *
     * @param error
     */
    void onLoginFailed(String error);

}

然后是model层定义接口

public interface Imodel {
    /**
     * 登录
     *
     * @param user
     * @return 约定返回"true"为登录成功,其他为登录失败的错误信息
     */
    String login(User user);

}

创建model层usermodel实现它
public class Usermodel implements Imodel{


    @Override
    public String login(User user) {
        boolean networkError = false; //网络是否异常

        try {
            Thread.sleep(3000);//模拟网络连接
            if (networkError) {
                return "网络异常";
            } else if ("ethanco".equals(user.getUsername()) && "123456".equals(user.getPassword())) {
                return "true";
            } else {
                return "账号或密码错误";
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
}

接下来是presenter层进行逻辑处理

public class UserPresenter {
    private final Iview userView;
    private final Usermodel userMode;

    public UserPresenter(Iview userView) {
        this.userView = userView;
        this.userMode = new Usermodel();
    }
    /**
     * 登录
     *
     * @param user
     */
    public void login(final User user) {
        new Thread() {
            @Override
            public void run() {
                final String res = userMode.login(user);
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if ("true".equals(res)) {
                            userView.onLoginSuccess();
                        } else {
                            userView.onLoginFailed(res);
                        }
                    }
                });
            }
        }.start();
    }




}

在MainActivity里引用

public class MainActivity extends AppCompatActivity implements Iview,View.OnClickListener{

    private EditText edituser;
    private  EditText editpass;
    private ProgressDialog loginProgreess;
    private UserPresenter userPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edituser = (EditText) findViewById(R.id.editText);
        editpass = (EditText) findViewById(R.id.editText2);
        findViewById(R.id.button).setOnClickListener(this);
       userPresenter = new UserPresenter(this);
    }

    @Override
    public void onClick(View v) {
        String username = edituser.getText().toString().trim();
        String password = editpass.getText().toString().trim();

        if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
            Toast.makeText(getApplicationContext(), "账号或密码不能为空", Toast.LENGTH_SHORT).show();
            return;
        }

        loginProgreess = ProgressDialog.show(this, "登录", "正在登录...");
        userPresenter.login(new User(username, password));

    }

    @Override
    public void onLoginSuccess() {
        loginProgreess.dismiss();
        Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLoginFailed(String error) {
        loginProgreess.dismiss();
        Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show();
    }
}

MainActivity的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.mvpdemo.MainActivity">

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="150dp"
android:hint="请输入用户名"
android:textSize="30dp"
android:id="@+id/editText" />

<Button
android:text="登陆"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/editText2"
android:layout_centerHorizontal="true"
android:layout_marginTop="141dp"
android:textSize="30dp"
android:id="@+id/button" />

<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:layout_marginTop="103dp"
android:hint="请输入密码"
android:textSize="30dp"
android:id="@+id/editText2"
android:layout_below="@+id/editText"
android:layout_centerHorizontal="true" />
    </RelativeLayout>

主要的东西的定义接口,接口回调,还有在presenter里的逻辑处理,开始接触还是有难度的,记住MVP
  • View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
    • Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
    • 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
    MVC模式:
    • View可以与Model直接交互
    • Controller是基于行为的,并且可以被多个View共享
    • 可以负责决定显示哪个View











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值