Android中Mvp模式的使用

来源:互联网 发布:网络游戏修改数据 编辑:程序博客网 时间:2024/04/28 03:31

现在在为下个项目做准备,之前一直都是使用 MVC模式去开发的,感觉业务什么的还是不够清晰,所以想在下一个项目中使用MVP模式进行开发,对MVP研究了一段时间时候,发表一下自己的见解,也动手写了一个简单的Demo,同时也希望路过的大神可以指点指点。

下面这一段解析是我引用这位大神的,原文链接:http://www.jianshu.com/p/ed2aa9546c2c
但是如果是第一次接触MVP模式或者接触不多的,我建议先不要看这些概念,直接先跳过对这三层的解析,看完我下面的Demo再回过头看会好点。
所谓MVP(Model-View-Presenter)模式。是将APP的结构分为三层:
view - UI显示层
view 层主要负责:
1. 提供UI交互
2. 在presenter的控制下修改UI。
3. 将业务事件交由presenter处理。
注意. View层不存储数据,不与Model层交互。

presenter - 逻辑处理层
presenter 层主要负责:
1. 对UI的各种业务事件进行相应处理。也许是与Model层交互,也许自己进行一些计算,也许控制后台Task,Servic
2. 对各种订阅事件进行响应,修改UI。
3. 临时存储页面相关数据。
注意. Presenter内不出现View引用。

model - 数据层
model层主要负责:
1. 从网络,数据库,文件,传感器,第三方等数据源读写数据。
2. 对外部的数据类型进行解析转换为APP内部数据交由上层处理。
3. 对数据的临时存储,管理,协调上层数据请求。

废话不多说了,直接贴代码展示我的Demo
效果图如下
这里写图片描述

这种功能是开发中比较常见的。
大概功能:
第一次进入页面先显示加载Progressbar,然后模拟获取数据,获取到的数据加载RecyclerView,完了就隐藏Progressbar,显示内容。
页面增加了下拉刷新、上拉加载更多功能、每一个item的监听。

然后Presenter类就可以定下来了:
如果别人是使用MVP模式开发的话,看Activity或Fragment使用的的Presenter就可以清晰的了解到这个页面的业务功能与逻辑。像看下面这个类就可以知道有什么业务

public interface IBabaPresenter {    /**     * 加载数据     */    void loadData();    /**     * 下拉刷新数据     */    void refreshData();    /**     * 上拉加载数据     */    void loadMoreData();    /**     * 每一条item的点击     */    void itemClick(Object obj);}

因为是Demo,我就随便的定了Model的字段
数据的承载体,在这里可以添加数据处理的方法,在这里我就随便写了个方法。比如如果在登录模块,可以做电话号码的验证啊之类的。反正就是与数据有关的处理。

public class BabaModel {    public String name;    /**     * 是不是 巴巴托斯 字段的判断     */    public boolean isBabaTuoSi(String text) {        if (text.contains("巴巴托斯")) {            return true;        }        return false;    }}

最后一个就是View类:
处理界面的逻辑。在这个例子,界面要做的事情抽取出来。

public interface IBabaView {    /**     * 拿到数据后,加载RecyclerView     *     * @param mDatas     */    void loadView(List<BabaModel> mDatas);    /**     * 做下拉刷新     */    void doRefresh(List<BabaModel> mDatas);    /**     * 做上拉加载     */    void doLoadMore(List<BabaModel> mDatas);    /**     * 每一个item的点击     */    void itemClick(Object obj);    /**     * 显示加载进度条     */    void showLoadingProgressBar();    /**     * 隐藏进度条     */    void hideLoadingProgressBar();}

然后就做相关的实现类了。BabaPresenterComplete
在这里我使用Handler做了延迟加载,仿网络访问的效果。
这个类的重点是在构造函数,传入IBabaView 做参数,然后我们就获取IBabaView 的引用进行对UI的处理了,但是这里不会出现对view的引用,像项目中的recyclerView、progressbar不会出现在这里。

/** * 作者:Leo on 2016/10/14 10:30 * <p/> * 描述:处理业务事件,切换修改界面UI,要注意的是:这个类里面不会出现对View的引用 */public class BabaPresenterComplete implements IBabaPresenter {    private IBabaView iBabaView;    public BabaPresenterComplete(IBabaView iBabaView) {        this.iBabaView = iBabaView;    }    @Override    public void loadData() {        iBabaView.showLoadingProgressBar();        iBabaView.loadView(getDatas());        //给点延时。仿网络加载        Handler handler = new Handler(Looper.getMainLooper());        handler.postDelayed(new Runnable() {            @Override            public void run() {                iBabaView.hideLoadingProgressBar();            }        }, 2000);    }    @Override    public void refreshData() {        //给点延时。仿网络加载        Handler handler = new Handler(Looper.getMainLooper());        handler.postDelayed(new Runnable() {            @Override            public void run() {                iBabaView.doRefresh(getDatas());            }        }, 2000);    }    @Override    public void loadMoreData() {        //给点延时。仿网络加载        Handler handler = new Handler(Looper.getMainLooper());        handler.postDelayed(new Runnable() {            @Override            public void run() {                iBabaView.doLoadMore(getDatas());            }        }, 2000);    }    @Override    public void itemClick(Object obj) {        iBabaView.itemClick(obj);    }    //模拟从网络获取数据    public List<BabaModel> getDatas() {        List<BabaModel> datas = new ArrayList<>();        for (int i = 0; i < 8; i++) {            BabaModel babaModel = new BabaModel();            if (i % 2 == 0) {                babaModel.name = "巴巴托斯" + new Random().nextInt(100);            } else {                babaModel.name = "独角兽" + new Random().nextInt(100);            }            datas.add(babaModel);        }        return datas;    }}

然后展示的是Activity
创建BabaPresenterComplete 的对象,在这里具体实现IBabaView,View 的引用全部都留在Activity中。但是调用会放在BabaPresenterComplete 中调用。

public class ListActivity extends AppCompatActivity implements IBabaView, OnMyItemClickListener {    private Toolbar toolbar;    private XRecyclerView recyclerView;    private LinearLayout llytProgress;    private BabaAdapter babaAdapter;    private BabaPresenterComplete babaPresenterComplete;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_list);        toolbar = (Toolbar) findViewById(R.id.toolbar);        toolbar.setTitle("初加载、刷新、加载更多、点击");        llytProgress = (LinearLayout) findViewById(R.id.progressBar);        recyclerView = (XRecyclerView) findViewById(R.id.recyclerview);        LinearLayoutManager layoutManager = new LinearLayoutManager(this);        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);        recyclerView.setLayoutManager(layoutManager);        recyclerView.setLoadingMoreEnabled(true);        recyclerView.setPullRefreshEnabled(true);       //看这里        babaPresenterComplete = new BabaPresenterComplete(this);        babaPresenterComplete.loadData();        recyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {            @Override            public void onRefresh() {                babaPresenterComplete.refreshData();            }            @Override            public void onLoadMore() {                babaPresenterComplete.loadMoreData();            }        });    }    @Override    public void loadView(List<BabaModel> mDatas) {        babaAdapter = new BabaAdapter(this, mDatas);        recyclerView.setAdapter(babaAdapter);        babaAdapter.setOnMyItemClickListener(this);    }    @Override    public void doRefresh(List<BabaModel> mDatas) {        if (babaAdapter != null) {            babaAdapter.addRefreshDatas(mDatas);        }        recyclerView.refreshComplete();    }    @Override    public void doLoadMore(List<BabaModel> mDatas) {        if (babaAdapter != null) {            babaAdapter.addLoadMoreDatas(mDatas);            //隐藏进度条            recyclerView.loadMoreComplete();        }    }    @Override    public void itemClick(Object obj) {        if (((BabaModel) obj).isBabaTuoSi(((BabaModel) obj).name))            Toast.makeText(this, "点击了 巴巴托斯", Toast.LENGTH_SHORT).show();        else            Toast.makeText(this, "点击的不是巴巴托斯,会被打的", Toast.LENGTH_SHORT).show();    }    @Override    public void showLoadingProgressBar() {        recyclerView.setVisibility(View.GONE);        llytProgress.setVisibility(View.VISIBLE);    }    @Override    public void hideLoadingProgressBar() {        llytProgress.setVisibility(View.GONE);        recyclerView.setVisibility(View.VISIBLE);    }    @Override    public void onItemClick(Object obj, int position) {        babaPresenterComplete.itemClick(obj);    }}

看到这里你会发现使用MVP模式开发,项目的业务逻辑会很清晰,如果去修改相关的功能,你会很快的找到去修改。
并且如果增加了需求,像如果当前页面增加一个重刷页面的按钮,不想修改BabaPresenterComplete 的话,也可以多写一个IReloadPresenter,里面就是包含reload的方法,因为java支持多实现;

public interface IBabaReloadView {    /**     * 重新加载     */    void reloadView();}public interface IBabaReloadPresenter {    /**     * 所有重新加载     */    void reloadAll();}


总结一下,其实对MVP现在还不是很熟悉,但是写这个Demo算是为下一个项目做准备吧。可能等我使用MVP模式去做完下一个项目的话,会对MVP有更深入的认识,学无止境啊。

也希望路过的大神或者对MVP有见解的,指点一下。小六不胜感激。

源码地址

0 0
原创粉丝点击