Android MVP框架模式

曾无好事来相访,赖尔高文一起予。这篇文章主要讲述Android MVP框架模式相关的知识,希望能为你提供帮助。
结合前一篇MVC框架模式
为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生。       在MVP模式里通常包含4个要素:       (1)View:负责绘制UI元素、与用户进行交互(在android中体现为Activity);       (2)View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;       (3)Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);       (4)Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。  

Android MVP框架模式

文章图片
 
 
MVP模式步骤:
1、创建一个IView让Presenter去依赖接口,不管数据时从哪里来,只要提供接口。
2、让Activity或者Fragment去实现接口,实现所有View的操作。
3、创建主持人,注入IView的接口,数据都从接口中获取。
4、创建Model,实现数据加载(网络、数据路、假数据)
5、使用主持人访问Model,获取数据后,调用IView去刷新布局。

  还是使用藏头诗接口的例子
布局文件
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1xmlns:tools="http://schemas.android.com/tools" 2android:id="@+id/activity_main" 3android:layout_width="match_parent" 4android:layout_height="match_parent" 5android:orientation="vertical" 6tools:context="com.example.lesson_mvc_cangtoushi.ui.MainActivity"> 7 8< RadioGroup 9android:id="@+id/rg_57" 10android:layout_width="match_parent" 11android:layout_height="wrap_content" 12android:orientation="horizontal"> 13 14< RadioButton 15android:id="@+id/rb_5" 16android:layout_width="0dp" 17android:layout_height="wrap_content" 18android:layout_weight="1" 19android:gravity="center" 20android:text="五言诗" /> 21 22< RadioButton 23android:id="@+id/rb_7" 24android:layout_width="0dp" 25android:layout_height="wrap_content" 26android:layout_weight="1" 27android:gravity="center" 28android:text="七言诗" /> 29< /RadioGroup> 30 31< RadioGroup 32android:id="@+id/rg_ct" 33android:layout_width="match_parent" 34android:layout_height="wrap_content" 35android:orientation="horizontal"> 36 37< RadioButton 38android:id="@+id/rb_ct" 39android:layout_width="0dp" 40android:layout_height="wrap_content" 41android:layout_weight="1" 42android:gravity="center" 43android:text="藏头" /> 44 45< RadioButton 46android:id="@+id/rb_cw" 47android:layout_width="0dp" 48android:layout_height="wrap_content" 49android:layout_weight="1" 50android:gravity="center" 51android:text="藏尾" /> 52 53< RadioButton 54android:id="@+id/rb_cz" 55android:layout_width="0dp" 56android:layout_height="wrap_content" 57android:layout_weight="1" 58android:gravity="center" 59android:text="藏中" /> 60 61< RadioButton 62android:id="@+id/rb_dz" 63android:layout_width="0dp" 64android:layout_height="wrap_content" 65android:layout_weight="1" 66android:gravity="center" 67android:text="递增" /> 68 69< RadioButton 70android:id="@+id/rb_dj" 71android:layout_width="0dp" 72android:layout_height="wrap_content" 73android:layout_weight="1" 74android:gravity="center" 75android:text="递减"/> 76 77< /RadioGroup> 78 79< RadioGroup 80android:id="@+id/rg_yy" 81android:layout_width="match_parent" 82android:layout_height="wrap_content" 83android:orientation="horizontal"> 84 85< RadioButton 86android:id="@+id/rb_1y" 87android:layout_width="0dp" 88android:layout_height="wrap_content" 89android:layout_weight="1" 90android:gravity="center" 91android:text="双句一押" /> 92 93< RadioButton 94android:id="@+id/rb_2y" 95android:layout_width="0dp" 96android:layout_height="wrap_content" 97android:layout_weight="1" 98android:gravity="center" 99android:text="双句押韵" /> 100 101< RadioButton 102android:id="@+id/rb_3y" 103android:layout_width="0dp" 104android:layout_height="wrap_content" 105android:layout_weight="1" 106android:gravity="center" 107android:text="一三四押" /> 108< /RadioGroup> 109< EditText 110android:id="@+id/et_key" 111android:layout_width="match_parent" 112android:layout_height="wrap_content" 113android:hint="请输入藏头诗"/> 114< Button 115android:id="@+id/btn_submit" 116android:layout_width="match_parent" 117android:layout_height="wrap_content" 118android:text="提交"/> 119 120< ScrollView 121android:layout_width="match_parent" 122android:layout_height="match_parent"> 123< TextView 124android:id="@+id/tv_show" 125android:layout_width="match_parent" 126android:layout_height="match_parent" /> 127< /ScrollView> 128 129 130 131 < /LinearLayout>

activity_main.xml  java代码目录结构。可以看出MVP多了一个Presenter,主持人,还有一个View接口,极大的实现了解耦
Android MVP框架模式

文章图片

 
藏头诗对象原型bean
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public class CangTouShiBean { 2 3 4/** 5* showapi_res_code : 0 6* showapi_res_error : 7* showapi_res_body : {"ret_code":0,"list":["北风勇士马,晚水独芙蓉。吾将宝非宝,英雄徒自强。","朝骑五花马,太华三芙蓉。吾将宝非宝,天子贵文强。","请歌牵白马,菡萏金芙蓉。大位天下宝,自从冒顿强。","青丝系五马,秀出九芙蓉。迈德惟家宝,日来知自强。","北买党项马,美女夸芙蓉。河宗来献宝,十年思自强。","青丝系五马,大嫂采芙蓉。药妙灵仙宝,不独有文强。"]} 8*/ 9 10private int showapi_res_code; 11private String showapi_res_error; 12private ShowapiResBodyBean showapi_res_body; 13 14 15@Override 16public String toString() { 17return "CangTouShiBean{" + 18"showapi_res_code=" + showapi_res_code + 19", showapi_res_error=\'" + showapi_res_error + \'\\\'\' + 20", showapi_res_body=" + showapi_res_body + 21\'}\'; 22} 23 24public int getShowapi_res_code() { 25return showapi_res_code; 26} 27 28public void setShowapi_res_code(int showapi_res_code) { 29this.showapi_res_code = showapi_res_code; 30} 31 32public String getShowapi_res_error() { 33return showapi_res_error; 34} 35 36public void setShowapi_res_error(String showapi_res_error) { 37this.showapi_res_error = showapi_res_error; 38} 39 40public ShowapiResBodyBean getShowapi_res_body() { 41return showapi_res_body; 42} 43 44public void setShowapi_res_body(ShowapiResBodyBean showapi_res_body) { 45this.showapi_res_body = showapi_res_body; 46} 47 48public static class ShowapiResBodyBean { 49/** 50* ret_code : 0 51* list : ["北风勇士马,晚水独芙蓉。吾将宝非宝,英雄徒自强。","朝骑五花马,太华三芙蓉。吾将宝非宝,天子贵文强。","请歌牵白马,菡萏金芙蓉。大位天下宝,自从冒顿强。","青丝系五马,秀出九芙蓉。迈德惟家宝,日来知自强。","北买党项马,美女夸芙蓉。河宗来献宝,十年思自强。","青丝系五马,大嫂采芙蓉。药妙灵仙宝,不独有文强。"] 52*/ 53 54private int ret_code; 55private List< String> list; 56 57 58@Override 59public String toString() { 60return "ShowapiResBodyBean{" + 61"ret_code=" + ret_code + 62", list=" + list + 63\'}\'; 64} 65 66public int getRet_code() { 67return ret_code; 68} 69 70public void setRet_code(int ret_code) { 71this.ret_code = ret_code; 72} 73 74public List< String> getList() { 75return list; 76} 77 78public void setList(List< String> list) { 79this.list = list; 80} 81} 82 }

CangTouShiBean.java藏头诗Model实现藏头诗接口,请求数据,将结果回调出去
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public interface BeanCallback< T> { 2 3void onError(String msg); 4void onSuccess(T t); 5 }

BeanCallback.java
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public interface ICangTouShi { 2//请求数据,需要有变化的参数 3void doRequest(String num, String type, String yayuntype, String key, BeanCallback< CangTouShiBean> callback); 4 5 }

ICangTouShi.java
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public class CangTouShiModel implements ICangTouShi { 2@Override 3public void doRequest(String num, String type, String yayuntype, String key, final BeanCallback< CangTouShiBean> callback) { 4 5//请求数据 6//使用OkHttp 7 8OkHttpClient client = new OkHttpClient(); 9 10RequestBody body = new FormBody.Builder() 11.add("showapi_appid","27306") 12.add("showapi_sign","150e9206e7f542bab4affe49d73cb920") 13.add("num",num) 14.add("type",type) 15.add("yayuntype",yayuntype) 16.add("key",key).build(); 17 18Request request = new Request.Builder() 19.post(body) 20.url("http://route.showapi.com/950-1").build(); 21okhttp3.Call call = client.newCall(request); 22//异步请求,子线程 23call.enqueue(new Callback() { 24@Override 25public void onFailure(okhttp3.Call call, IOException e) { 26Log.e("TAG","-----------"+e.getMessage()); 27callback.onError(e.getMessage()); 28} 29 30@Override 31public void onResponse(okhttp3.Call call, Response response) throws IOException { 32String json = response.body().string(); 33Gson gson = new Gson(); 34CangTouShiBean bean = gson.fromJson(json, CangTouShiBean.class); 35callback.onSuccess(bean); 36} 37 38}); 39 40} 41 42 }

CangTouShiModel.java定义一个View的接口,声明一个些方法
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public interface IMvpView { 2 3String getNum(); 4 5String getType(); 6 7String getYY(); 8 9String getKey(); 10 11void showDialog(); 12 13void dismissDialog(); 14 15void setText(String text); 16 17void showToast(String msg); 18 19 }

IMvpView.java定义了主持人Presenter,构造方法传入以个IMvpView的对象,声明了一个CangTouModel的对象,并在构造的时候创建。然后就可以用着两个引用的方法,请求数据
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public class MvpPresenter { 2IMvpView iMvpView; 3ICangTouShi cangTouShi; 4 5public MvpPresenter(IMvpView iMvpView){ 6this.iMvpView = iMvpView; 7cangTouShi = new CangTouShiModel(); 8} 9 10public void getData(){ 11//判断key不能为null 12if(iMvpView.getKey().equals("")){ 13iMvpView.showToast("Key不能为空"); 14return; 15} 16iMvpView.showDialog(); 17 18cangTouShi.doRequest(iMvpView.getNum(), iMvpView.getType(), iMvpView.getYY(), iMvpView.getKey(), new BeanCallback< CangTouShiBean> () { 19@Override 20public void onError(String msg) { 21iMvpView.showToast(msg); 22iMvpView.dismissDialog(); 23} 24 25@Override 26public void onSuccess(CangTouShiBean cangTouShiBean) { 27String msg = ""; 28for (String s : cangTouShiBean.getShowapi_res_body().getList()) { 29msg += s+"\\n"; 30} 31iMvpView.setText(msg); 32iMvpView.dismissDialog(); 33} 34}); 35 36} 37 }

MvpPresenter.java【Android MVP框架模式】  MainActivity加载视图,实现IMvpView的接口,实现里面的方法,拿到Presenter的对象,调用getData获取到数据。
Android MVP框架模式

文章图片
Android MVP框架模式

文章图片
1 public class MainActivity extends AppCompatActivity implements IMvpView, View.OnClickListener { 2 3RadioGroup rg_57, rg_ct, rg_yy; 4EditText et_key; 5Button btn_submit; 6TextView tv_show; 7 8MvpPresenter presenter; 9 10@Override 11protected void onCreate(Bundle savedInstanceState) { 12super.onCreate(savedInstanceState); 13setContentView(R.layout.activity_main); 14 15initView(); 16presenter = new MvpPresenter(this); 17} 18 19 20private void initView() { 21rg_57 = (RadioGroup) findViewById(R.id.rg_57); 22rg_57.check(R.id.rb_5); 23rg_ct = (RadioGroup) findViewById(R.id.rg_ct); 24rg_ct.check(R.id.rb_ct); 25rg_yy = (RadioGroup) findViewById(R.id.rg_yy); 26rg_yy.check(R.id.rb_1y); 27et_key = (EditText) findViewById(R.id.et_key); 28btn_submit = (Button) findViewById(R.id.btn_submit); 29tv_show = (TextView) findViewById(R.id.tv_show); 30btn_submit.setOnClickListener(this); 31 32 33} 34 35@Override 36public String getNum() { 37return rg_57.getCheckedRadioButtonId() == R.id.rb_5 ? "5" : "7"; 38} 39 40@Override 41public String getType() { 42String type = null; 43switch (rg_ct.getCheckedRadioButtonId()){ 44case R.id.rb_ct: 45type = "1"; 46break; 47case R.id.rb_cw: 48type = "2"; 49break; 50case R.id.rb_cz: 51type = "3"; 52break; 53case R.id.rb_dz: 54type = "4"; 55break; 56case R.id.rb_dj: 57type = "5"; 58break; 59} 60return type; 61} 62 63@Override 64public String getYY() { 65String yy= null; 66switch (rg_yy.getCheckedRadioButtonId()){ 67case

    推荐阅读