传统的MVP:

1、抽离出View的接口,即ILoginView。

2、抽离Model的接口,即ILoginModel。

3、抽离Presenter的接口,即ILoginPresenter。

4、实现ILoginView 接口的 LoginActivity。

5、实现ILoginModel 接口的 LoginModel。

6、实现ILoginPresenter 接口的 LoginPresenter。

LoginActivity:实现ILoginView 接口以及初始化ILoginPresenter

 public class LoginActivity extends BaseActivity implements ILoginView {
private ILoginPresenter mPresenter; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); mPresenter = new LoginPresenter(this);
} public void onUserLogin(View view) { mPresenter.login(userName, password);
}
}

LoginPresenter:

public class LoginPresenter implements ILoginPresenter {

    private ILoginView mView;
private ILoginModel mModel; public LoginPresenter() {
init();
} public LoginPresenter(ILoginView view) {
mView = view;
init();
} private void init() {
mModel = new LoginModel(this);
}
}

下面改造后抽离后的MVP:

1、抽离出View的接口,即LoginView。

2、抽离Model的接口:使用rxjava 可以避免传入各种CallBack进行结果返回。

  (1)网络层:LoginRepository。

  (2)数据缓存层:LoginCache。

3、根据Model 层,抽离 Presenter层 :LoginPresenter。

4、实现LoginView 接口的 LoginActivity。

5、实现LoginRepository 接口的 LoginRepositoryImpl。

6、(如需要数据缓存,以及缓存操作的)实现LoginCache 接口的 LoginCacheImpl。

7、实现LoginPresenter 接口的 LoginPresenterImpl。

下面例子:

(1)用户界面输入用户名密码,点击登录按钮,出现进度条,进行接口请求.

(2)登陆成功,进度条消失,跳转.

(3)登陆失败,进度条消失,Toast失败原因

布局文件:

 <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"tools:context=".MainActivity"> <EditText
android:layout_width="match_parent"
android:id="@+id/et_username"
android:hint="input user name"
android:layout_height="wrap_content" /> <EditText
android:layout_width="match_parent"
android:id="@+id/et_password"
android:hint="input user password"
android:layout_height="wrap_content" /> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onUserLogin"
android:text="登录"/> </LinearLayout>

View :

 public interface LoginView {

        void showProgress();

        void dismissProgress();

        void onLoginFail(String error);

        void goToActivity();
}

Activity :

 public class LoginActivity extends AppCompatActivity implements LoginView {

         private EditText userNameEdit;
private EditText pwdEdit;
private ProgressDialog dialog; private LoginPresenter presenter = new LoginPresenterImpl(this); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews();
} private void initViews() {
userNameEdit = (EditText) findViewById(R.id.tv_username);
pwdEdit = (EditText) findViewById(R.id.tv_password);
} public void onUserLogin(View v){
String userName = userNameEdit.getText().toString().trim(); String password = pwdEdit.getText().toString().trim();
presenter.login(userName, password);// 登录
} @Override
public void showProgress() {
if(dialog==null){
dialog = ProgressDialog.show(this,"","loading...");
}else{
if(!dialog.isShowing()){
dialog.show();
}
}
} @Override
public void dismissProgress() {
if(dialog!=null&&dialog.isShowing()){
dialog.dismiss();
}
} @Override
public void onLoginFail(final String error) {
// 提示登录失败
} @Override
public void goToActivity() {
// 登录成功跳转到其他页面
}
}

Model,网络层:

public interface LoginReposity {
// 在网络请求当中,可以一个模块一个Repository
// 在数据缓存当中,可以一个模块一个Cache
Observable<JSONObject> login(String userName,String password);
}

Model,网络层实现类:

public class LoginReposityImpl  {

    public LoginRepositoryImpl(){}

    @Override
public Observable<JSONObject> login() {
return Observable.create(new Observable.OnSubscribe<JSONObject>() {
@Override
public void call(Subscriber<? super JSONObject> subscriber) {
// 模拟请求登录成功返回json数据
JSONObject json = new JSONObject();
subscriber.onNext(json);
subscriber.onCompleted();
}
});
}
}

Presenter:

 public interface LoginPresenter {

     void login(String userName, String password);
}

presenter实现类:

 public class LoginPresenterImpl implements LoginPresenter {

     private LoginRepository repository;

     private LoginView view;

     public LoginPresenterImpl(LoginView _view){
view = _view;
repository = new LoginRepositoryImpl();
} public void login(String userName, String password){ if(TextUtils.isEmpty(userName)||TextUtils.isEmpty(password)){
view.onLoginFail("请完善登录信息");
return;
}
view.showProgress();
repository.login(userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() { } @Override
public void onError(Throwable e) {
view.dismissProgress();
view.onLoginFail(error.getMessage());
} @Override
public void onNext(Boolean aBoolean) {
view.dismissProgress();
view.goToActivity();
}
}));
}
}

Android MVP 利用rxjava 避免向Model传入监听方法的更多相关文章

  1. Android修行之路------List view无法获取监听方法

    注意: 1.在list view自定义布局中如果添加滚动布局,会导致自定义布局无法获取监听. 2.如果ListView的每项布局里有像Button,ImageButton之类View的控键时,这些Vi ...

  2. Android下 scrollview的滚动停止事件的监听方法

    使用递归调用的方法,每隔5毫秒检查一下是否已经停止,如果已经停止,就拿到事件啦! 不扯蛋,直接上代码. scrollContent就是我的scrollview. [代码]java代码: ? 1 2 3 ...

  3. DataTable和DataRow利用反射直接转换为Model对象的扩展方法类

    DataTable和DataRow利用反射直接转换为Model对象的扩展方法类   /// <summary> /// 类 说 明:给DataTable和DataRow扩展方法,直接转换为 ...

  4. Android开发之手势滑动(滑动手势监听)详解

    Android开发之手势滑动(滑动手势监听)详解 在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListen ...

  5. Android软键盘的隐藏显示、事件监听的代码

    把开发过程中重要的一些内容片段做个珍藏,如下资料是关于Android软键盘的隐藏显示.事件监听的内容,应该是对小伙伴们有所用途. public class ResizeLayout extends L ...

  6. android CheckBox控件的定义及事件监听

    http://www.beijibear.com/index.php?aid=336 android CheckBox控件的定义及事件监听,本例实现CheckBox控件的定义及点击事件的监听并显示结果 ...

  7. Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听

    原文:Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听 简单记录下android 盒子开发遥控器的监听 ,希望能帮到新入门的朋友们 不多说,直接贴代码 public cla ...

  8. Android MVP+Retrofit+RxJava实践小结

    关于MVP.Retrofit.RxJava,之前已经分别做了分享,如果您还没有阅读过,可以猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava ...

  9. Android的事件处理机制详解(二)-----基于监听的事件处理机制

    基于监听的事件处理机制 前言: 我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应 这就涉及到了android的事件处理机制; android给我们提供了两套功能强大的处理机制 ...

随机推荐

  1. Meterpreter run vnc 遇到的问题

    Metasploit框架中的meterpreter无疑是相当强大的工具,而且具有我目前挺喜欢的vnc.但是我在run vnc时发现得到的远程控制桌面是view-only的,通过-h选项发现没有修改的方 ...

  2. shell 脚本中的运算

    #!/bin/bash read -p "please Insert two integer values: " a b if [ ! -n "$a" -o ! ...

  3. How do I get the path of the current executed file in Python?

    First, you need to import from inspect and os from inspect import getsourcefile from os.path import ...

  4. 数据库如何生成sql语句

    以SQL SERVER 2008为例子. 1.启动客户端管理器,连接到要生成脚本的数据库. 2.在左边的”对象资源管理器“中,右键选择该数据库打开菜单.选择”任务“,”生成脚本“菜单,打开对话框. 3 ...

  5. 自定义注解之运行时注解(RetentionPolicy.RUNTIME)

    对注解概念不了解的可以先看这个:Java注解基础概念总结 前面有提到注解按生命周期来划分可分为3类: 1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成clas ...

  6. Shell 获取指定行的内容

    需求: 有一个文件,根据指定的字符串,得到该字符串上两行的内容. 文件内容如下: linux-56:# cat sys.ttconnect.ini # Copyright (C) 1999, 2006 ...

  7. express框架

    一.express的使用 安装express 在根目录下输入 npm install express 引入express的包 const express = require("express ...

  8. sublime text3 前端插件介绍

    Emmet插件 Emmet插件可以说是使用Sublime Text进行前端开发必不可少的插件 它让编写HTML代码变得极其简单高效 基本用法:输入标签简写形式,然后按Tab键 关于Emmet的更多介绍 ...

  9. 阿里云CentOS7系列一 -- 安装JDK7的方法.

    最近因为数据采集以及生产环境冲突.导入windows Server 2008系统经常死机.经讨论决定把采集服务程序和生产服务进行分开.采集程序通过windows Server2008运行.而生产程序通 ...

  10. 常用Javascript语法

    1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4. ...