Android MVP框架模式
结合前一篇MVC框架模式
MVP模式步骤:
1、创建一个IView让Presenter去依赖接口,不管数据时从哪里来,只要提供接口。
2、让Activity或者Fragment去实现接口,实现所有View的操作。
3、创建主持人,注入IView的接口,数据都从接口中获取。
4、创建Model,实现数据加载(网络、数据路、假数据)
5、使用主持人访问Model,获取数据后,调用IView去刷新布局。
还是使用藏头诗接口的例子
布局文件
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.lesson_mvc_cangtoushi.ui.MainActivity"> <RadioGroup
android:id="@+id/rg_57"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <RadioButton
android:id="@+id/rb_5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="五言诗" /> <RadioButton
android:id="@+id/rb_7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="七言诗" />
</RadioGroup> <RadioGroup
android:id="@+id/rg_ct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <RadioButton
android:id="@+id/rb_ct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="藏头" /> <RadioButton
android:id="@+id/rb_cw"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="藏尾" /> <RadioButton
android:id="@+id/rb_cz"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="藏中" /> <RadioButton
android:id="@+id/rb_dz"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="递增" /> <RadioButton
android:id="@+id/rb_dj"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="递减"/> </RadioGroup> <RadioGroup
android:id="@+id/rg_yy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <RadioButton
android:id="@+id/rb_1y"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="双句一押" /> <RadioButton
android:id="@+id/rb_2y"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="双句押韵" /> <RadioButton
android:id="@+id/rb_3y"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="一三四押" />
</RadioGroup>
<EditText
android:id="@+id/et_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入藏头诗"/>
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="提交"/> <ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_show"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView> </LinearLayout>
activity_main.xml
java代码目录结构。可以看出MVP多了一个Presenter,主持人,还有一个View接口,极大的实现了解耦
藏头诗对象原型bean
public class CangTouShiBean { /**
* showapi_res_code : 0
* showapi_res_error :
* showapi_res_body : {"ret_code":0,"list":["北风勇士马,晚水独芙蓉。吾将宝非宝,英雄徒自强。","朝骑五花马,太华三芙蓉。吾将宝非宝,天子贵文强。","请歌牵白马,菡萏金芙蓉。大位天下宝,自从冒顿强。","青丝系五马,秀出九芙蓉。迈德惟家宝,日来知自强。","北买党项马,美女夸芙蓉。河宗来献宝,十年思自强。","青丝系五马,大嫂采芙蓉。药妙灵仙宝,不独有文强。"]}
*/ private int showapi_res_code;
private String showapi_res_error;
private ShowapiResBodyBean showapi_res_body; @Override
public String toString() {
return "CangTouShiBean{" +
"showapi_res_code=" + showapi_res_code +
", showapi_res_error='" + showapi_res_error + '\'' +
", showapi_res_body=" + showapi_res_body +
'}';
} public int getShowapi_res_code() {
return showapi_res_code;
} public void setShowapi_res_code(int showapi_res_code) {
this.showapi_res_code = showapi_res_code;
} public String getShowapi_res_error() {
return showapi_res_error;
} public void setShowapi_res_error(String showapi_res_error) {
this.showapi_res_error = showapi_res_error;
} public ShowapiResBodyBean getShowapi_res_body() {
return showapi_res_body;
} public void setShowapi_res_body(ShowapiResBodyBean showapi_res_body) {
this.showapi_res_body = showapi_res_body;
} public static class ShowapiResBodyBean {
/**
* ret_code : 0
* list : ["北风勇士马,晚水独芙蓉。吾将宝非宝,英雄徒自强。","朝骑五花马,太华三芙蓉。吾将宝非宝,天子贵文强。","请歌牵白马,菡萏金芙蓉。大位天下宝,自从冒顿强。","青丝系五马,秀出九芙蓉。迈德惟家宝,日来知自强。","北买党项马,美女夸芙蓉。河宗来献宝,十年思自强。","青丝系五马,大嫂采芙蓉。药妙灵仙宝,不独有文强。"]
*/ private int ret_code;
private List<String> list; @Override
public String toString() {
return "ShowapiResBodyBean{" +
"ret_code=" + ret_code +
", list=" + list +
'}';
} public int getRet_code() {
return ret_code;
} public void setRet_code(int ret_code) {
this.ret_code = ret_code;
} public List<String> getList() {
return list;
} public void setList(List<String> list) {
this.list = list;
}
}
}
CangTouShiBean.java
藏头诗Model实现藏头诗接口,请求数据,将结果回调出去
public interface BeanCallback<T> { void onError(String msg);
void onSuccess(T t);
}
BeanCallback.java
public interface ICangTouShi {
//请求数据,需要有变化的参数
void doRequest(String num, String type, String yayuntype, String key, BeanCallback<CangTouShiBean> callback); }
ICangTouShi.java
public class CangTouShiModel implements ICangTouShi {
@Override
public void doRequest(String num, String type, String yayuntype, String key, final BeanCallback<CangTouShiBean> callback) { //请求数据
//使用OkHttp OkHttpClient client = new OkHttpClient(); RequestBody body = new FormBody.Builder()
.add("showapi_appid","27306")
.add("showapi_sign","150e9206e7f542bab4affe49d73cb920")
.add("num",num)
.add("type",type)
.add("yayuntype",yayuntype)
.add("key",key).build(); Request request = new Request.Builder()
.post(body)
.url("http://route.showapi.com/950-1").build();
okhttp3.Call call = client.newCall(request);
//异步请求,子线程
call.enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
Log.e("TAG","-----------"+e.getMessage());
callback.onError(e.getMessage());
} @Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
String json = response.body().string();
Gson gson = new Gson();
CangTouShiBean bean = gson.fromJson(json, CangTouShiBean.class);
callback.onSuccess(bean);
} }); } }
CangTouShiModel.java
定义一个View的接口,声明一个些方法
public interface IMvpView { String getNum(); String getType(); String getYY(); String getKey(); void showDialog(); void dismissDialog(); void setText(String text); void showToast(String msg); }
IMvpView.java
定义了主持人Presenter,构造方法传入以个IMvpView的对象,声明了一个CangTouModel的对象,并在构造的时候创建。然后就可以用着两个引用的方法,请求数据
public class MvpPresenter {
IMvpView iMvpView;
ICangTouShi cangTouShi; public MvpPresenter(IMvpView iMvpView){
this.iMvpView = iMvpView;
cangTouShi = new CangTouShiModel();
} public void getData(){
//判断key不能为null
if(iMvpView.getKey().equals("")){
iMvpView.showToast("Key不能为空");
return;
}
iMvpView.showDialog(); cangTouShi.doRequest(iMvpView.getNum(), iMvpView.getType(), iMvpView.getYY(), iMvpView.getKey(), new BeanCallback<CangTouShiBean>() {
@Override
public void onError(String msg) {
iMvpView.showToast(msg);
iMvpView.dismissDialog();
} @Override
public void onSuccess(CangTouShiBean cangTouShiBean) {
String msg = "";
for (String s : cangTouShiBean.getShowapi_res_body().getList()) {
msg += s+"\n";
}
iMvpView.setText(msg);
iMvpView.dismissDialog();
}
}); }
}
MvpPresenter.java
MainActivity加载视图,实现IMvpView的接口,实现里面的方法,拿到Presenter的对象,调用getData获取到数据。
public class MainActivity extends AppCompatActivity implements IMvpView, View.OnClickListener { RadioGroup rg_57, rg_ct, rg_yy;
EditText et_key;
Button btn_submit;
TextView tv_show; MvpPresenter presenter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
presenter = new MvpPresenter(this);
} private void initView() {
rg_57 = (RadioGroup) findViewById(R.id.rg_57);
rg_57.check(R.id.rb_5);
rg_ct = (RadioGroup) findViewById(R.id.rg_ct);
rg_ct.check(R.id.rb_ct);
rg_yy = (RadioGroup) findViewById(R.id.rg_yy);
rg_yy.check(R.id.rb_1y);
et_key = (EditText) findViewById(R.id.et_key);
btn_submit = (Button) findViewById(R.id.btn_submit);
tv_show = (TextView) findViewById(R.id.tv_show);
btn_submit.setOnClickListener(this); } @Override
public String getNum() {
return rg_57.getCheckedRadioButtonId() == R.id.rb_5 ? "5" : "7";
} @Override
public String getType() {
String type = null;
switch (rg_ct.getCheckedRadioButtonId()){
case R.id.rb_ct:
type = "1";
break;
case R.id.rb_cw:
type = "2";
break;
case R.id.rb_cz:
type = "3";
break;
case R.id.rb_dz:
type = "4";
break;
case R.id.rb_dj:
type = "5";
break;
}
return type;
} @Override
public String getYY() {
String yy= null;
switch (rg_yy.getCheckedRadioButtonId()){
case R.id.rb_1y:
yy="1";
break;
case R.id.rb_2y:
yy="2";
break;
case R.id.rb_3y:
yy="3";
break;
}
return yy;
} @Override
public String getKey() {
return et_key.getText().toString();
} ProgressDialog dialog;
@Override
public void showDialog() {
dialog = new ProgressDialog(this);
dialog.setTitle("提示");
dialog.setMessage("开始请求");
dialog.show();
} @Override
public void dismissDialog() {
dialog.dismiss();
} @Override
public void setText(final String text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_show.setText(text);
}
});
} @Override
public void showToast(final String msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
showToast(msg);
}
});
} @Override
public void onClick(View v) {
//通过主持人请求
presenter.getData();
}
}
MainActivity.java
- View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
- Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
- 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
- View可以与Model直接交互
- Controller是基于行为的,并且可以被多个View共享
- 可以负责决定显示哪个View
Android MVP框架模式的更多相关文章
- 如何实现自己的Android MVP框架?
相信熟悉android开发的童鞋对MVP框架应该都不陌生吧,网上很多关于android中实现MVP的文章,大家可以直接搜索学习.这些文章中,MVP的实现思路基本都是把Activity.Fragment ...
- 理解 Android MVP 开发模式
/***************************************************************************************** * 理解 Andr ...
- Android MVP开发模式及Retrofit + RxJava封装
代码已上传到Github,因为接口都是模拟无法进行测试,明白大概的逻辑就行了! 欢迎浏览我的博客--https://pushy.site 1. MVP模式 1.1 介绍 如果熟悉MVP模式架构的话,对 ...
- android MVP框架
原文地址:http://blog.csdn.net/guxiao1201/article/details/40147209 在开发Android应用时,相信很多同学遇到和我一样的情况,虽然项目刚开始构 ...
- Android MVC框架模式
MCV model view controller 模型-视图-控制写 M层:适合做一些业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在model层处理. V层:应用层中处 ...
- MVP框架模式
一.基本概念 MVP是Model-View-Presenter的简称,即模型-视图-表现层的缩写.MVP是由MVC模式进化而来的,MVP改进了MVC中的控制器过于臃肿的问题.与MVC一样,MVP将应用 ...
- Android基础——框架模式MVC在安卓中的实践
本篇文章包含以下内容: MVC的介绍 MVC的实践 MVC的介绍 MVC (Model View Controller),是模型(model)视图(view)控制器(controller)的缩写,一种 ...
- Android MVP框架实现登录案例
一.Model package com.czhappy.mvpdemo.model; /** * author: chenzheng * created on: 2019/5/16 11:06 * d ...
- android mvp高速开发框架介绍(dileber的简单介绍)
今天我为大家介绍一款android mvp框架:dileber(https://github.com/dileber/dileber.git) 官方交流qq群:171443726 我个人qq:2971 ...
随机推荐
- request.getContextPath获取绝对路径
request.getContextPath获取绝对路径 博客分类: 经验+注意 其他 request.getContextPath 项目需求:所有jsp页必须通过Action转发,不能直接在地址栏链 ...
- mysqldump: command not found问题解决
首先得知道mysql命令或mysqldump命令的完整路径,可以使用find命令查找除非你知道mysql安装路径可以略过这一步. find / -name mysql -print 例如我的mysql ...
- NewRowNeeded和UserAddedRow事件以及RowsAdded的区别使用
NewRowNeeded事件当 VirtualMode 属性为 true 时,将在用户定位到 DataGridView 底部的新行时发生,适合给新行建立一些默认数据和按规则应该产生的数据,但此时不推荐 ...
- Bootstrap_表单_表单样式
一.基础表单 <form > <div class="form-group"> <label>邮箱:</label> <inp ...
- 【技术宅4】如何把M个苹果平均分给N个小朋友
$apple=array('apple1','apple2','apple3','apple4','apple5','apple6','apple7','apple8','apple9','apple ...
- IE8 不支持Date.now()
Date.now() 返回1970 年 1 月 1日午夜与当前日期和时间之间的毫秒数. 以下是微软的描述: 在早于 Internet Explorer 9 的安装版本中不受支持. 但是,在以下文档模式 ...
- DM9000C网卡驱动程序移植
1.取消版本号不符终止程序运行 2.iobase基地址修改为s3c3440的0x20000000 3.网卡使用的中断号改为IRQ_EINT7 4.中断触发方式改为上升沿触发 5.设置S3C2440的m ...
- 开发Nginx模块
开发Nginx模块 前面的哪些话 关于Nginx模块开发的博客资料,网上很多,很多.但是,每篇博客都只提要点,无法"step by step"照着做,对于初次接触Nginx开发的同 ...
- ios+oc面试题
ios+oc面试题 浅复制和深复制的区别?//浅拷贝和深拷贝答案:浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身.//通过对象的指针来访问这个对象深层复制(mutableCo ...
- java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码
java 动态代理深度学习, 一.相关类及其方法: java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxyInstance()返回一个指定 ...