关闭

MVP入门篇之一 - 基本使用 HelloMVP

标签: mvpandroid
50人阅读 评论(0) 收藏 举报
分类:

一些水话

这是我写的第一篇博客,姑且是对自己学习android的总结吧,自2015年在大三上学期开始自学android,到现在即将步入职场,已经过去了整整一年有余,就写下一些希望对自己和别人有用的东西吧!博客以后会不定期的更新有关于Java和android语言的知识,欢迎大家留言斧正.


MVP模式

MVP模式可以分离显示层和逻辑层,它们之间通过接口进行通信.
假设Activity既负责显示数据又负责获取数据,耦合性太高,导致我们在日后假如要修改UI(V层),还要涉及到对原来的业务逻辑的抽离,如果使用了MVP模式,我们不需要担心这个问题,而且可以对独立的各个模块进行单元测试,

这里写图片描述
Activity负责显示数据
获取数据的任务交给Presenter(方法为:调用Presenter的方法>>load),不负责获取数据.

Presenter请求数据
获取的方式:交给M层(业务逻辑层)
在MainActivityPresenter类中调用了来自MvpModelInter接口的抽象方法,由于MainActivityModel已经调用了实现了该类,所以必须要重写该方法在这个方法中获取了数据后调用MvpModelInter中的一个监听接口OnLoadCompleteListeneronLoadComplete方法

@Override
    public void getData(OnLoadCompleteListener onLoadCompleteListener) {

        // 获取数据
        getDataList(list);

        // 该回调方法会把数据传递出去,Presenter会重写这个方法
        // 用接口回调, 要么通过构造方法传过来一个接口对象,要么参数传递过来
        // 谁传过来?->P层,本例中没有从View层中传递过来的引用
        onLoadCompleteListener.onLoadComplete(list);
    }

    private void getDataList(List<String> list) {
        for (int i = 0; i < 100; i++) {
            list.add("这是MVP 创建的数据" + i);
        }
    }

Presenter获取请求到的数据
model获取完之后怎么把数据传回来?
回调接口MvpModelInter的getData方法>>mvpModel.getData(要调用这个方法必须要在括号里重写监听接口的抽象方法);

mvpModel.getData(new MvpModelInter.OnLoadCompleteListener() {
    @Override
    public void onLoadComplete(List<String> list) {
        //获取到来自M层的数据>List<String> list
        //回调来自V层的方法,并传入要传递的数据,这个方法会在Activity中被重写
        mvpView.showView(list);
    }
});

这样最终数据会传递到Presenter中
Presenter的构造方法中实现了MvpModelInter的类

MainActivityModel:
public MainActivityPresenter(MvpViewInter mvpView) {
    this.mvpView = mvpView;
    mvpModel = new MainActivityModel();//----------这里
}

然后由Presenter再想办法通知activity>告诉的方式
因为MainActivity实现了MvpViewInter接口

MainActivity extends Activity implements MvpViewInter 

在调用请求获取数据的时候有这样一条语句
MainActivity中:

new MainActivityPresenter(MainActivity.this).load();

MainActivityPresenter中
public MainActivityPresenter(MvpViewInter mvpView) {
    this.mvpView = mvpView;//----------这里
    mvpModel = new MainActivityModel();
}

因此Presenter的构造方法在调用的时候已经创建了一个MvpViewInter对象,
此时我们通过调用对应的接口方法把数据传给 MainActivity,然后MainActivity因为实现了MvpViewInter接口重写了showView
我们在showView方法中更新数据即可

代码由三个类

MainActivity

package com.example.mvpfirststep;

import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.example.mvpfirststep.view.MvpViewInter;
import com.example.presenter.MainActivityPresenter;


public class MainActivity extends Activity implements MvpViewInter {

    private ListView mListView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.lv_listview);
        // Activity 只能展示数据
        // 需要Presenter获取数据>调用Presenter的方法>>MainActivityPresenter(MvpViewInter mvpView).load
        new MainActivityPresenter(MainActivity.this).load();
    }

    /**
     * 获取到数据>>更新界面
     * 
     * @param list
     */
    @Override
    public void showView(List<String> list) {
        ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, list);
        mListView.setAdapter(adapter);
    }

}

MainActivityPresenter

package com.example.presenter;

import java.util.List;

import com.example.model.MainActivityModel;
import com.example.model.MvpModelInter;
import com.example.mvpfirststep.view.MvpViewInter;

public class MainActivityPresenter {

    private MvpModelInter mvpModel;
    private MvpViewInter mvpView;

    public MainActivityPresenter(MvpViewInter mvpView) {
        this.mvpView = mvpView;
        mvpModel = new MainActivityModel();
    }

    public void load() {
        mvpModel.getData(new MvpModelInter.OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(List<String> list) {
                // 获取到来自M层的数据>List<String> list
                // 回调来自V层的方法,并传入要传递的数据,这个方法会在Activity中被重写
                mvpView.showView(list);
            }
        });
    }

}

MainMvpModel

package com.example.model;

import java.util.ArrayList;
import java.util.List;

// Model 业务逻辑层
public class MainActivityModel implements MvpModelInter {

    private List<String> list = new ArrayList<>();

    @Override
    public void getData(OnLoadCompleteListener onLoadCompleteListener) {

        // 获取数据
        getDataList(list);

        // 该回调方法会把数据传递出去,Presenter会重写这个方法
        // 用接口回调, 要么通过构造方法传过来一个接口对象,要么参数传递过来
        // 谁传过来?->P层,本例中没有从View层中传递过来的引用
        onLoadCompleteListener.onLoadComplete(list);
    }

    private void getDataList(List<String> list) {
        for (int i = 0; i < 100; i++) {
            list.add("这是MVP 创建的数据" + i);
        }
    }
}

两个接口

MvpView

package com.example.mvpfirststep.view;

import java.util.List;

public interface MvpViewInter {

    void showView(List<String> list);
}

MvpModel

package com.example.model;

import java.util.List;

public interface MvpModelInter {

    void getData(OnLoadCompleteListener listener);

    public interface OnLoadCompleteListener {
        void onLoadComplete(List<String> list);
    }
}

至于布局文件相当简单,就一个activity_main放了一个ListView
文档目录如下:
文档目录

总结

想要基本使用MVP模式,必须对接口回调具有深入的理解,建议在这方面还有理解困难的同学可以使用Viso画出一个思维导图,顺便向大家推荐一款不错的软件:XMind,这款软件可以用来画出很漂亮的思维导图,帮助大家理清思路

下一个部分我准备写一篇关于在MVP中使用虚引用的博客,需要用到的知识点有接口回调,泛型,大家也可以想想为什么使用虚引用,这样做有什么好处?

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7049次
    • 积分:258
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:18篇
    • 译文:0篇
    • 评论:3条
    最新评论