第一篇博客讲一个用MVP模式写RecyclerView的案例,通过这个例子了解一下MVP模式。
一、什么是MVP模式
MVP是模型(Model)、视图(View)、驱动器(Presenter)的缩写,分别代表项目中3个不同的模块。
模型(Model):负责处理数据的加载或者存储,比如从网络或本地数据库获取数据等;
视图(View):负责界面数据的展示,与用户进行交互,在presenter的控制下修改UI;
驱动器(Presenter):协调中心,是模型与视图之间的桥梁,将模型与视图分离开来。
MVP模式其实就是一套适合Android开发的成熟规范,MVP模式由MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。但是他们的内部联系不尽相同,我们先从两张图区分MVC和MVP
我们可以看到MVC是三端一环控制一环形成一个循环而MVP以Presenter为驱动,双向调动View和Model,其中在View层定义Presenter,调用Presenter的方法实现逻辑功能,在Presenter定义View和Model,Presenter则可调用Model获取数据后再调用View层的方法更新View层,而Model层中与Presenter的联系以回调实现。
二、优势
大大减少了Model与View层之间的耦合度。一方面可以使得View层和Model层单独开发与测试,互不依赖。View层只要写出所有界面变化的方法而不用考虑什么时候调用,而Presenter则只写出所有的逻辑代码,当需要数据时向Model层调用,需要更新界面时则调用View层方法,完全不需考虑界面的更新的实现和数据获取的代码实现。另一方面Presenter和Model层都可以封装复用,可以极大的减少代码量。
三、案例演示
先看效果图
接下来写接口:
三层统一用一个Contact接口,然后里面在写三个内部接口(View、Model、Presenter),到时候相应的每个实现类实现不同的内部接口即可,把每一层的方法都写上
public interface MyContact {
interface View {
//toast显示信息
void showToast(String string);
//设置recyclerView
void setAdapter(InvitationBaseBean invitationBaseBean);
//刷新adater
void notifyAdapter();
//停止刷新
void stopRefresh();
}
interface InvitationlModel{
//http请求获取数据
void getData(StringCallback stringCallback);
}
interface InvitationPresenter {
//连接、断开view
void attachView(@NonNull MainActivity View);
void detachView();
//获取数据
void getData();
//加载更多
void pullLoadMore();
}
}
1:view层:
View层主要是一个RecyclerView,SuperSwipeRefesh,然后每个Item里面也有一个用户头像的RecyclerView
MainActivity.Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/activity_bg"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/invitation_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/custom_toolbar"/>
<net.mobctrl.views.SuperSwipeRefreshLayout
android:id="@+id/invitation_refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/activity_my_focus_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</net.mobctrl.views.SuperSwipeRefreshLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/invitation_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/launch" />
</android.support.design.widget.CoordinatorLayout>
Item.Layout
item里面在嵌套一个横向RecyclerView,显示参与用户头像
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/tools"
android:id="@+id/item_invitation_root"
android:orientation="vertical"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:background="@color/white"
android:paddingRight="15dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginBottom="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_invitation_originator_imagVi"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/user_img" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height=