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 ...
随机推荐
- SGU 138.Games of Chess
时间限制:0.25s 空间限制:4M 题目: n个朋友在一起按照下面的规则依次下棋:在第一局游戏,n个人中的两个开始下棋.在第二局,第一局胜利的人将跟其他人下棋(也可能还是输了第一局人), 在第三局第 ...
- 那些年被我坑过的Python——不得不知(第二章)
问题一: Python3.5.X中的数据类型有哪些? 答:包括整型.布尔型.字符串型.浮点型.复数.列表.字典.集合.元组. 细化来说: 1.整型包括短整型和长整型,不过我们不必过度操心细节,因为短整 ...
- ASP.NET MVC 定义JsonpResult实现跨域请求
1:原理 在js中,XMLHttpRequest是不能请求不同域的数据,但是script标签却可以,所以可以用script标签实现跨域请求.具体是定义一个函数,例如jsonp1234,请求不同域的ur ...
- 误差逆传播(error BackPropagation, BP)算法推导及向量化表示
1.前言 看完讲卷积神经网络基础讲得非常好的cs231后总感觉不过瘾,主要原因在于虽然知道了卷积神经网络的计算过程和基本结构,但还是无法透彻理解卷积神经网络的学习过程.于是找来了进阶的教材Notes ...
- InfiniBand技术简介
InfiniBand技术简介 转载请在文首保留原文出处:EMC中文支持论坛https://community.emc.com/go/chinese 介绍 随着CPU和通讯处理速度的 ...
- [HDOJ 5155] Harry And Magic Box
题目链接:HDOJ - 5155 题目大意 有一个 n * m 的棋盘,已知每行每列都至少有一个棋子,求可能有多少种不同的棋子分布情况.答案对一个大素数取模. 题目分析 算法1: 使用容斥原理与递推. ...
- 基于LeanCloud云引擎的Web全栈方案
LeanEngine-Full-Stack The FULL STACK DEVELOPER 复杂的项目, 协作分工, 自动化流程,代码组织结构,框架选择,国际化方案等 Generator 或者See ...
- JAVA内置的观察者模式样本
DisplayElement.java public interface DisplayElement { public void display(); } CurrentConditionsDisp ...
- Replicate String in C#
My original posting on string repetition caused a couple responses, and is currently among the Top P ...
- 使用next-key locks 用于搜索和索引扫描,可以防止幻读
Next-Key Locks A next-key lock is a combination of a record lock on the index record and a gap lock ...