Android MVP模式就是这么回事儿

概念就不说了,大家都懂。View层通过Persenter层相互通信,避免了View中大量的业务代码,而将其提取到Model中。其实简单的来说,就是通过接口回调,把业务分离出去。提高代码的可读性和已维护性。
直接看案例就明白了。
-----------------------------

案例(用户登录)

常规的用户登录写法就是Activity(fragment)中获取用户名密码,网络请求登录接口,返回是否登录成功
而MVP的模式就是,要把网络请求这一部分单独提取出来放到model层里面,View层也就是我们的Activity只写页面相关的操作,

创建LoginModel如下:

package com.cyq.mvppractice.model; public class LoginModel { public static boolean login(String username, String password) { //一般是请求网络接口咯 //具体逻辑我就不写了,这里模拟一下,直接返回登录成功 return true; } }

很简单,就是一个常规类和常规操作而已,处理具体的登录网络请求

定义一个接口LoginInterface和LoginPersenter类
LoginInterface中又定义了两个接口,View和Persenter分别继承这两个接口,实现View和Persenter层的交互,具体如下

package com.cyq.mvppractice.contract; public interface LoginInterface { /** * View层需要继承这个接口,通过接口方法View层获取返回结果 */ interface View { //判断是否登录成功 void isLogin(boolean islogin); } /** * persenter需要继承的接口,通过接口方法传入View层的值 */ interface Persenter { //model层需要哪些传入数据从这个接口传入 void goLogin(String username, String password); } }

LoginPersenter.class

package com.cyq.mvppractice.persenter; import com.cyq.mvppractice.contract.LoginInterface; import com.cyq.mvppractice.model.LoginModel; public class LoginPersenter implements LoginInterface.Persenter { //通过构造方法传入view,相当于传入了activity和fragment private LoginInterface.View view; public LoginPersenter(LoginInterface.View view) { this.view = view; } /** * 调用model层业务,最终通过view.isLogin(b),通知view层获取数据 * * @param username * @param password */ @Override public void goLogin(String username, String password) { boolean isLogin = LoginModel.login(username, password); //回调通知View层 view.isLogin(isLogin); } }

最后在View中继承LoginInterface.View接口,实例化LoginInterface.Persenter接口

package com.cyq.mvppractice; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.Toast; import com.cyq.mvppractice.contract.LoginInterface; import com.cyq.mvppractice.persenter.LoginPersenter; public class LoginActivity extends AppCompatActivity implements LoginInterface.View { private LoginInterface.Persenter mPersenter; private EditText usernameEt, passwordEt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); mPersenter = new LoginPersenter(this); usernameEt = findViewById(R.id.et_username); passwordEt = findViewById(R.id.et_password); findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String usernameStr = usernameEt.getText().toString(); String passwordStr = passwordEt.getText().toString(); if ((!TextUtils.isEmpty(usernameStr)) && (!TextUtils.isEmpty(passwordStr))) mPersenter.goLogin(usernameStr, passwordStr); else { Toast.makeText(LoginActivity.this, "请输入用户名或密码", Toast.LENGTH_SHORT).show(); } } }); } @Override public void isLogin(boolean islogin) { if (islogin) { Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show(); } } }

就这么简单,把网络请求数据库操作等复杂业务单独放到model层中处理,通过接口回调获得model处理结果返回到View层,也就避免了在View层编写大量的业务逻辑了

Xml布局如下,就是两个Edittext和一个登陆按钮

<?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:padding="20dp" tools:context=".LoginActivity"> <EditText android:id="@+id/et_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入用户名" /> <EditText android:id="@+id/et_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:hint="请输入密码" /> <Button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="登录" /> </LinearLayout>

没看懂?再认真看一遍,再写个小demo就ok了,主要是理解其思想

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjdsx.html