安卓mvp学习

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学习 - 阿里云

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

m:

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

v:

public interface ReceiveAddressListView {
publicvoidsetRectViewData(ListviewData);
}

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

publicvoidseWvtUrl(String url);

p:
BasePresenter

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

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

package com.test.mvp.mode;
/**
* Created by Administrator on 2017/8/7.
*/
public class AddressList {
public Stringname;
public Stringphone;
public Stringaddress;
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 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 Handlerhandler=new Handler();
//下拉刷新状态
public finalint REFRESH_STATUS=1;
public booleanisLoad=false;
//上拉加载更多状态
public finalint LOADING_STATUS=2;
private final ReceiveAddressListActivity receiveAddressListActivity;
privateArrayListaddressLists=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() {
ArrayListlists=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中 实现列表加载,那我肯定需要一个设置 列表的的方法,我也不知道怎么实现。但是我可以先声明,需要这个方法,这个方法如何去实现,怎么做我不关心

publicvoidsetRectViewData(ListviewData);

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

public void getPageData(intstate,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

效果:

安卓mvp学习 - 阿里云

大神参考:
https://mp.weixin.qq.com/s?__biz=MzI1MDc5ODA4OA==∣=2247483664&;idx=1&;sn=9417a191b7eec1c9d395b40e317de387&;chksm=e9fd8877de8a016154f69da6d8da997b9dc81e6807c0ea126c88ab591ef68f22fa8ae7412b74∓share=1⪰ne=23&;srcid=0806rXyKuEQJgN6y9i0Q7NbE#rd