以前对mvp设计框架只是停留在只听其声,不见其人的状态下,2018年初入职的新公司,项目就是以mvp框架设计的(主要还是方便做单元测试),所以接下来的两篇博客会是通过自己写的项目来彻彻底底的描述mvp的设计理念。
MVP的设计模式最重要的特点就是view层与model层的彻底解耦,中间加入present层,present层会持有view层和model层的对象引用,并通过接口互相通信(IView/IModel)。
一、mvp与mvc相比较的优点
1.activity职责更为明确,ui逻辑以及使用哪一个表示层更为清晰;
2.代码结构更清楚,更容易维护;
3.方便单元测试;
4.避免activity的内存泄漏。
二、我的demo中的结构设计如下图所示:
布局文件:
xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.wangsujuan.mvpdemo1.MainActivity"> android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"/>
布局文件只有一个简单的listview。
GirlAdapter类是继承baseadapter类的布局适配器,bean包下的girl类是实体类。
接下来看看view层下的BaseActivity类:
public abstract class BaseActivity<V, T extends BasePresenter<V>> extends AppCompatActivity{ public T girlPresenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); girlPresenter = createPresenter(); girlPresenter.attachView((V)this); } protected abstract T createPresenter(); @Override protected void onDestroy() { girlPresenter.detachView(); super.onDestroy(); } }
再看看BasePresenter类,这个类是负责与BaseActivity绑定和解绑的,以免发生内存泄漏,再看看BasePresenter类:
public class BasePresenter<T> { public WeakReference<T> mViewRef; public void attachView(T view) { mViewRef = new WeakReference<T>(view); } public void detachView() { mViewRef.clear(); } }
view层的IGirlView接口,对外提供给present层的两个接口,里面主要是从接收外部传过来List
public interface IGirlView { void showLoading(); void showGirls(Listgirls); }
再看看GirlPresent类:
public class GirlPresenter<T extends IGirlView> extends BasePresenter<T> { IGirlModel girlModel = new GirlModelImpl(); public void fetch() { if (mViewRef.get() != null) { mViewRef.get().showLoading(); if (girlModel != null) { girlModel.loadGirl(new IGirlModel.GirlOnLoadListener() { @Override public void onComplete(Listgirls) { if (mViewRef.get() != null) { mViewRef.get().showGirls(girls); } } }); } } } }
model层是负责处理数据的,也是通过接口来对外通信:
public class GirlModelImpl implements IGirlModel { @Override public void loadGirl(GirlOnLoadListener girlOnLoadListener) { Listdata = new ArrayList (); data.add(new Girl(R.drawable.f1, "sdafew*", "123潮流女个性字母印花无袖露脐上衣")); data.add(new Girl(R.drawable.f2, "四颗星", "迷依诗诺夏天新款韩版女装性感夜店欧美风字母印花牛仔露脐背心上衣")); data.add(new Girl(R.drawable.f3, "五颗星", "迷依诗诺春夏欧美新款性感女装单排扣牛仔背心露脐上衣")); data.add(new Girl(R.drawable.f4, "三颗星", "美莉丹 新款欧美单排扣牛仔背心露脐上衣")); data.add(new Girl(R.drawable.f5, "五颗星", "夏季新款韩版时尚个性字母无袖露脐上衣")); data.add(new Girl(R.drawable.f6, "三颗星", "新款欧美单排扣牛仔背心露脐上衣")); data.add(new Girl(R.drawable.f7, "四颗星", "夏装新款下摆波浪边挂脖露肩")); data.add(new Girl(R.drawable.f8, "五颗星", "夏天新款欧美时尚潮流休闲百")); data.add(new Girl(R.drawable.f9, "四颗星", "迷依诗诺夏季新款小香风甜美性感夜")); data.add(new Girl(R.drawable.f10, "三颗星", "安巴克夏季新款韩版时尚套")); girlOnLoadListener.onComplete(data); } }
public interface IGirlModel { void loadGirl(GirlOnLoadListener girlOnLoadListener); interface GirlOnLoadListener { void onComplete(Listgirls); } }
最后来看看MainActivity类的代码:
public class MainActivity extends BaseActivity好了,总体的代码就这么多,github代码下载地址:https://github.com/cWX411904/mvpdemo, GirlPresenter > implements IGirlView{ private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.listview); girlPresenter.fetch(); } @Override protected GirlPresenter createPresenter() { return new GirlPresenter(); } @Override public void showLoading() { Toast.makeText(this, "加载成功", Toast.LENGTH_SHORT).show(); } @Override public void showGirls(List girls) { listView.setAdapter(new GirlAdapter(this, girls)); }