Android中Mvp模式的使用

本文通过一个实例展示了MVP模式在Android应用开发中的应用,详细解释了Model、View和Presenter三个组件的功能划分,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在在为下个项目做准备,之前一直都是使用 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有见解的,指点一下。小六不胜感激。

源码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值