介绍:
现在UI技术的不断增强,UI层履行越来越多的职责,为了更好的细分视图层和模型层的功能,让View层更专注于处理数据的可视化与用户的交互,让Model层只去处理数据操作,相互不干扰,同时对于项目的单元测试和今后的项目维护都有着非常好的作用。因此,MVP模式是不可或缺的法宝。。。
MVP模式中包含3个主要元素:
- Model层:负责处理数据,可进行获取、存储、操作等功能。一般单独创建一个class,并且为了降低耦合度,也会创建一个Model Interface接口。同时还会创建一个和数据有关的接口listener,进行数据传递。让PresenterImplement类来实现该listener,进行数据交互。
- View层:负责绘制UI, 展示数据,与用户进行交互。一般体现为Activity和Fragment,来实现View Interface接口,与Presenter进行交互。
- Presenter层:负责处理View层与Model层之间的逻辑。传入View Interface,创建Model Impl类,实现listener,进行数据的处理。
优点:
- 降低代码耦合度。
- 模块职责划分明显。
- 代码复用度提高。
- 代码灵活性高。
- 利于测试。
- 方便后期维护。
项目目录结构:
目录结构简洁鲜明,一看就懂。。。
深入理解,看代码:
- ImageFragment类:
实现View Interface和listener,用来展示UI界面和Presenter交互。
public class
ImageFragment
extends
Fragment
implements
ImageView,
SwipeRefreshLayout.OnRefreshListener {
private static final
String
TAG
=
"ImageFragment"
;
private
SwipeRefreshLayout
mSwipeRefreshWidget
;
private
RecyclerView
mRecyclerView
;
private
LinearLayoutManager
mLayoutManager
;
private
ImageAdapter
mAdapter
;
private
List<ImageBean>
mData
;
private
ImagePresenter
mImagePresenter
;
@Override
public void
onCreate
(
@Nullable
Bundle savedInstanceState) {
super
.onCreate(savedInstanceState)
;
mImagePresenter = new ImagePresenterImpl(this);
}
@Nullable
@Override
public
View
onCreateView
(LayoutInflater inflater
,
ViewGroup container
,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.
fragment_image
, null
)
;
mSwipeRefreshWidget
= (SwipeRefreshLayout) view.findViewById(R.id.
swipe_refresh_widget
)
;
mSwipeRefreshWidget
.setColorSchemeResources(R.color.
primary
,
R.color.
primary_dark
,
R.color.
primary_light
,
R.color.
accent
)
;
mSwipeRefreshWidget
.setOnRefreshListener(
this
)
;
mRecyclerView
= (RecyclerView)view.findViewById(R.id.
recycle_view
)
;
mRecyclerView
.setHasFixedSize(
true
)
;
mLayoutManager
=
new
LinearLayoutManager(getActivity())
;
mRecyclerView
.setLayoutManager(
mLayoutManager
)
;
mRecyclerView
.setItemAnimator(
new
DefaultItemAnimator())
;
mAdapter
=
new
ImageAdapter(getActivity().getApplicationContext())
;
mRecyclerView
.setAdapter(
mAdapter
)
;
mRecyclerView
.addOnScrollListener(
mOnScrollListener
)
;
onRefresh()
;
return
view
;
}
private
RecyclerView.OnScrollListener
mOnScrollListener
=
new
RecyclerView.OnScrollListener() {
private int
lastVisibleItem
;
@Override
public void
onScrolled
(RecyclerView recyclerView
, int
dx
, int
dy) {
super
.onScrolled(recyclerView
,
dx
,
dy)
;
lastVisibleItem
=
mLayoutManager
.findLastVisibleItemPosition()
;
}
@Override
public void
onScrollStateChanged
(RecyclerView recyclerView
, int
newState) {
super
.onScrollStateChanged(recyclerView
,
newState)
;
if
(newState == RecyclerView.
SCROLL_STATE_IDLE
&&
lastVisibleItem
+
1
==
mAdapter
.getItemCount() ) {
//加载更多
Snackbar.
make
(getActivity().findViewById(R.id.
drawer_layout
)
,
getString(R.string.
image_hit
)
,
Snackbar.
LENGTH_SHORT
).show()
;
}
}
}
;
@Override
public void
onRefresh
() {
mImagePresenter
.loadImageList()
;
}
@Override
public void
addImages
(List<ImageBean> list) {
if
(
mData
==
null
) {
mData
=
new
ArrayList<>()
;
}
mData
.clear()
;
mData
.addAll(list)
;
mAdapter
.setmDate(
mData
)
;
}
@Override
public void
showProgress
() {
mSwipeRefreshWidget
.setRefreshing(
true
)
;
}
@Override
public void
hideProgress
() {
mSwipeRefreshWidget
.setRefreshing(
false
)
;
}
@Override
public void
showLoadFailMsg
() {
if
(isAdded()) {
View view = getActivity() ==
null
?
mRecyclerView
.getRootView() : getActivity().findViewById(R.id.
drawer_layout
)
;
Snackbar.
make
(view
,
getString(R.string.
load_fail
)
,
Snackbar.
LENGTH_SHORT
).show()
;
}
}
}
- View层接口类:
/**
* 图片的view层接口
*/
public interface
ImageView {
//添加图片
void
addImages
(List<ImageBean> list)
;
//展示加载框
void
showProgress
()
;
//隐藏加载框
void
hideProgress
()
;
//显示加载失败的信息
void
showLoadFailMsg
()
;
}
- Presenter层接口与实现类:
/**
* 图片的presenter层的接口
*/
public interface
ImagePresenter {
void
loadImageList
()
;
}
/**
* 图片的presenter层的接口实现类
*/
public class
ImagePresenterImpl
implements
ImagePresenter
,
ImageModelImpl.OnLoadImageListListener {
private
ImageModel
mImageModel
;
private
ImageView
mImageView
;
public
ImagePresenterImpl
(ImageView imageView) {
//引入model和view
this.mImageModel = new ImageModelImpl();
this.mImageView = imageView;
}
@Override
public void
loadImageList
() {
//显示加载框和加载数据列表
mImageView
.showProgress()
;
mImageModel
.loadImageList(
this
)
;
}
@Override
public void
onSuccess
(List<ImageBean> list) {
mImageView
.addImages(list)
;
mImageView
.hideProgress()
;
}
@Override
public void
onFailure
(String msg
,
Exception e) {
mImageView
.hideProgress()
;
mImageView
.showLoadFailMsg()
;
}
}
- Model层接口、实现类和listener接口:
/**
* 图片的model层接口
*/
public interface
ImageModel {
/**
* 加载图片列表
*
@param
listener
加载图片成功或失败的监听接口
*/
void
loadImageList
(ImageModelImpl.OnLoadImageListListener listener)
;
}
/**
* 图片model层的接口实现类
*/
public class
ImageModelImpl
implements
ImageModel {
/**
* 获取图片列表
*
@param
listener
*/
@Override
public void
loadImageList
(
final
OnLoadImageListListener listener) {
String url = Urls.
IMAGES_URL
;
OkHttpUtils.ResultCallback<String> loadNewsCallback =
new
OkHttpUtils.ResultCallback<String>() {
@Override
public void
onSuccess
(String response) {
//请求网络成功
List<ImageBean> iamgeBeanList = ImageJsonUtils.
readJsonImageBeans
(response)
;
listener
.onSuccess(iamgeBeanList)
;
}
@Override
public void
onFailure
(Exception e) {
listener
.onFailure(
"load image list failure."
,
e)
;
}
}
;
OkHttpUtils.
get
(url
,
loadNewsCallback)
;
}
/**
* 加载图片成功或失败的监听接口
*/
public interface OnLoadImageListListener {
void onSuccess(List<ImageBean> list);
void onFailure(String msg, Exception e);
}
}
总结:
以上代码就是对MVP模式的简单解释,不理解的可以多看几遍,或者可以再查阅一些资料,方便理解,MVP模式基本上都是在大型的项目中使用,不过用之前需要深入理解,不然在实际项目中会让自己的逻辑发生混乱,导致项目崩溃。