安卓mvp学习

来源:互联网 发布:淘宝订单留言在哪里 编辑:程序博客网 时间:2024/05/22 16:50

mvp模式是目前安卓开发中比较火由大神提出的开发模式,其作用是更好的将项目中代码分层,便于维护,但是在实际开发过程中,一个activity中,要加上m,v,p层,也就是会最少加上3个类来维护,无形中会加大工作量,由于逻辑会分到m,v,p 层中去维护,也就是打断了连贯性,阅读起来更加吃力,如果注释不到位,那就很坑了,不管如何这都是一个优秀的开发模式,值得学习


什么是mvp

  • M:M层,也就是我们在程序中经常出现的model层,他的功能就是处理数据,其他任务不由他来接手。

  • V:V层,我们的view层,也就是显示数据的地方,我们在得到数据之后,把数据传递给view层,通过他来显示数据。同时,view层的点击事件等处理会在这里出现,但真正的数据处理不是在这里,而是在model层中处理。

  • P:P层,也就是Presenter层,他是我们mvp架构中的中间人,通过p层的连接,让我们可以是M层和V层进行通信。M层在获取到数据之后,把它交给P,P层在交给View层,同样,View层的点击事件等处理通过P层去通知M层,让他去进行数据处理。

这里写图片描述

如何来实现MVP模式,
将m,v,p抽象出来,建立接口,定义规范

m:

在项目中没有定义mode层的抽象类,所以这里没写。

v:

public interface ReceiveAddressListView {    public  void  setRectViewData(List<AddressList>  viewData);}

代码中存在recyclerview,需要给列表设置数据源,抽象一个方法出来,如果要给webview 加载URL,我们可以抽象一个方法出来

public  void  seWvtUrl(String url);

p:
BasePresenter

public interface BasePresenter {    public void getPageData(int  state,int page);}

定义了m,v,p三个接口后,然后分别来实现
m:

package com.test.mvp.mode;/** * Created by Administrator on 2017/8/7. */public class AddressList {    public String  name;    public String  phone;    public String  address;    public AddressList(String name, String phone, String address) {        this.name = name;        this.phone = phone;        this.address = address;    }    public void setName(String name) {        this.name = name;    }    public void setPhone(String phone) {        this.phone = phone;    }    public void setAddress(String address) {        this.address = address;    }    public String getName() {        return name;    }    public String getPhone() {        return phone;    }    public String getAddress() {        return address;    }}

mode 负责维护数据源

v:

package com.test.mvp;import android.content.Context;import android.content.Intent;import android.support.v4.widget.SwipeRefreshLayout;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import com.test.mvp.View.ReceiveAddressListView;import com.test.mvp.mode.AddressList;import com.test.mvp.presenter.ReceiveAddressListPresenter;import java.util.List;/** * Created by Administrator on 2017/8/7. */public class ReceiveAddressListActivity extends BaseActivity implements ReceiveAddressListView, SwipeRefreshLayout.OnRefreshListener {    private RecyclerView rcView;    private ReceiveAddressListPresenter presenter;    private ReceiveAddressListAdapter listAdapter;    private SwipeRefreshLayout swiperefresh;    private LinearLayoutManager layoutManager;    private int lastVisibleItem=0;    @Override    protected int initView() {        return R.layout.activity_receive_address_list;    }    @Override    protected void findViewById() {        rcView = (RecyclerView) findViewById(R.id.rcView);        swiperefresh = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);        swiperefresh.setOnRefreshListener(this);        initRecyclerView();    }    /**     * 初始化RecyclerView     */    private void initRecyclerView() {        layoutManager = new LinearLayoutManager(this);        rcView.setLayoutManager(layoutManager);        listAdapter = new ReceiveAddressListAdapter();        rcView.setAdapter(listAdapter);    }    @Override    protected void initPresenter() {        presenter = new ReceiveAddressListPresenter(this);    }    @Override    protected void setOnListener() {        rcView.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                if (newState == RecyclerView.SCROLL_STATE_IDLE                        && lastVisibleItem + 1 == listAdapter.getItemCount()) {                    // 此处在现实项目中,请换成网络请求数据代码,sendRequest .....                    presenter.getPageData(presenter.LOADING_STATUS, 2);                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                lastVisibleItem = layoutManager.findLastVisibleItemPosition();            }        });    }    @Override    protected void creterView() {        //这样做只是有动画效果不会刷新,所以同时还要调用onRefresh()这个方法        swiperefresh.post(new Runnable() {            @Override            public void run() {                swiperefresh.setRefreshing(true);                onRefresh();            }        });    }    /**     * 实现   ReceiveAddressListView  接口方法以便被调用     *     * @param viewData     */    @Override    public void setRectViewData(List<AddressList> viewData) {        swiperefresh.setRefreshing(false);        listAdapter.setRectViewData(viewData);    }    /**     * 刷新数据     */    @Override    public void onRefresh() {        presenter.getPageData(presenter.REFRESH_STATUS, 1);    }    protected static void start(Context context) {        Intent intent = new Intent(context, ReceiveAddressListActivity.class);        context.startActivity(intent);    }}

在activity中实现ReceiveAddressListView 这个接口,并且通过

  presenter = new ReceiveAddressListPresenter(this);

让p层持有view ,在activity中只会看到调用p层方法,完成逻辑处理

p:

package com.test.mvp.presenter;import android.os.Handler;import com.test.mvp.GetDataUtil;import com.test.mvp.ReceiveAddressListActivity;import com.test.mvp.mode.AddressList;import java.util.ArrayList;/** * Created by Administrator on 2017/8/7. */public class ReceiveAddressListPresenter implements BasePresenter{    private Handler  handler=new Handler();    //下拉刷新状态    public final  int REFRESH_STATUS=1;    public boolean  isLoad=false;    //上拉加载更多状态    public final  int LOADING_STATUS=2;    private final ReceiveAddressListActivity receiveAddressListActivity;    private  ArrayList<AddressList>  addressLists=new ArrayList<>();    public ReceiveAddressListPresenter(ReceiveAddressListActivity receiveAddressListActivity) {        this.receiveAddressListActivity=receiveAddressListActivity;    }    @Override    public void getPageData(final int state, final int page) {//这个地方进行网络请求        if (!isLoad)        {            isLoad=true;            handler.postDelayed(new Runnable() {                @Override                public void run() {                    ArrayList<AddressList>  lists=  GetDataUtil.getAddressList(page);                    if (state==REFRESH_STATUS)//刷新数据                    {                        addressLists=lists;                    }else {//上拉加载                        addressLists.addAll(lists);                    }                    receiveAddressListActivity.setRectViewData(addressLists);                    isLoad=false;                }            },1000);        }    }}

p 层getPageData方法中进行网络请求,得到数据后由于p层持有v层,就可以更改ui变化

总结一下:
mvp模式的实现,先是用接口方式声明自己要什么,然后实现类来具体干什么。
比如view层,在我这个demo中 实现列表加载,那我肯定需要一个设置 列表的的方法,我也不知道怎么实现。但是我可以先声明,需要这个方法,这个方法如何去实现,怎么做我不关心

public  void  setRectViewData(List<AddressList>  viewData);

接下再说p层,p层需要做什么其实跟v层对应,v层需要设置列表,那么就需要数据,数据哪里来,这个时候我们需要一个获得数据方法,那么我们声明一下:

   public void getPageData(int  state,int page);

同样这个获取数据的方法,如何实现,做什么操作,我们不关心

按照这个思路,我们基本可以确定v,p层的抽象方法,又可以说是接口层。m层去干什么呢,在实际开发中
并不需要去写一个接口model然后来实现,所以一般没写

准备好了接口方法,如何实现mvp,我们需要让activity实现ReceiveAddressListView,并且重载setRectViewData(); 这里实现如何去设置列表数据源。

同样ReceiveAddressListPresenter实现BasePresenter 接口完成p层实现,重载
getPageData();,p层持有v层

   public ReceiveAddressListPresenter(ReceiveAddressListActivity receiveAddressListActivity) {        this.receiveAddressListActivity=receiveAddressListActivity;    }
   public ReceiveAddressListPresenter(ReceiveAddressListView receiveAddressListActivity) {        this.receiveAddressListActivity=receiveAddressListActivity;    }

两种实现方式
我写了一个demo,用了两种方法来实现MVP
https://github.com/Followk/testmvp

效果:

这里写图片描述

大神参考:
https://mp.weixin.qq.com/s?__biz=MzI1MDc5ODA4OA==&mid=2247483664&idx=1&sn=9417a191b7eec1c9d395b40e317de387&chksm=e9fd8877de8a016154f69da6d8da997b9dc81e6807c0ea126c88ab591ef68f22fa8ae7412b74&mpshare=1&scene=23&srcid=0806rXyKuEQJgN6y9i0Q7NbE#rd

原创粉丝点击