Android MVP 写法

 前言

Model:负责数据逻辑

View:负责视图逻辑

Presenter:负责业务逻辑

持有关系:

1、View 持有 Presenter

2、Model 持有 Presenter

3、Presenter 持有 View

4、Presenter 持有 Model

辅助工具:ViewBinding

执行流程:View  ==> Presenter ==> Model ==> Presenter ==> View

案例效果图:

1、定义IPresenter接口

/*** 代理接口 负责业务逻辑*/
public interface IPresenter extends IBasePresenter {void setView(IView view);  // 持有 Viewvoid setModel(IModel model);  // 持有 Modelvoid onDataChanged(String data); // 时时修改Model的数据,由View通知 Presentervoid onDataChangedUpdateText(String data); // 修改View的TextView数据,由Model通知 Presentervoid submitFromData(); // 执行Model的 提交表单服务,由View通知 Presentervoid showSubmitFromLoading(String data); // 执行View的显示loading方法,由Model通知 Presentervoid hideSubmitFromLoading(); // 执行View的隐藏loading方法,由Model通知 Presentervoid clearData(); // 执行Model的 清空数据方法,由View通知 Presentervoid clearTextData(); // 执行View的清空TextView内容方法,由Model通知 Presenter}

1.1、实现IPresenter接口

/*** 具体业务逻辑实现*/
public class IPresenterImp implements IPresenter {private IView view;private IModel model;@Overridepublic void setView(IView view) {this.view = view;}@Overridepublic void removeHandlerMsgAndCallback() {model.removeHandlerMsgAndCallback();}@Overridepublic void setModel(IModel model) {this.model = model;}@Overridepublic void onDataChanged(String data) {model.onDataChanged(data);}@Overridepublic void onDataChangedUpdateText(String data) {view.onDataChangedUpdateText(data);}@Overridepublic void submitFromData() {model.submitFromData();}@Overridepublic void showSubmitFromLoading(String data) {view.showSubmitFromLoading(data);}@Overridepublic void hideSubmitFromLoading() {view.hideSubmitFromLoading();}@Overridepublic void clearData() {model.clearData();}@Overridepublic void clearTextData() {view.clearFromData();}}

2、定义Model接口

/*** 数据模型接口 负责数据逻辑*/
public interface IModel extends IBaseModel {default void setPresenter(IPresenter presenter) {}  // 持有 Presenter/*** 这些都是方法,都是由 Presenter 调用的*/void onDataChanged(String data); // 监听文本变化,时时更新数据void submitFromData(); // 提交表单数据void clearData(); // 清空数据}

2.1、实现Model接口

/*** 数据模型逻辑 具体实现*/
public class IModelImp implements IModel {private String mData = "";private IPresenter presenter;private Handler handler = new Handler();@Overridepublic void setPresenter(IPresenter presenter) {this.presenter = presenter;}@Overridepublic void onDataChanged(String data) {mData = data;presenter.onDataChangedUpdateText(mData);}@Overridepublic void removeHandlerMsgAndCallback() {handler.removeCallbacksAndMessages(null);}@Overridepublic void submitFromData() {presenter.showSubmitFromLoading(mData);handler.removeCallbacksAndMessages(null);handler.postDelayed(new Runnable() {@Overridepublic void run() {presenter.hideSubmitFromLoading();}}, 1500);}@Overridepublic void clearData() {mData = "";presenter.clearTextData();}
}

3、定义View接口

/*** 视图接口 负责视图逻辑*/
public interface IView extends IBaseView {default void setPresenter(IPresenter presenter) {} // 持有 Presenter/*** 这些都是方法,都是由 Presenter 调用的*/void onDataChangedUpdateText(String data); // 根据时时数据更新TextViewvoid showSubmitFromLoading(String data); // 显示提交表单loadingvoid hideSubmitFromLoading(); // 隐藏提交表单loadingvoid clearFromData(); // 清空EditText数据}

3.1、实现View接口

/*** 视图逻辑 具体实现*/
public class MVPActivity extends AppCompatActivity implements IView, View.OnClickListener {private ActivityMvpBinding binding;private IModel iModel;private IPresenter iPresenter;private AlertDialog dialog;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMvpBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());iPresenter = new IPresenterImp();iModel = new IModelImp();// 注意一下,写的顺序iModel.setPresenter(iPresenter); // 持有 PresentersetPresenter(iPresenter); // 持有 PresenteriPresenter.setModel(iModel); // 持有 ModeliPresenter.setView(this); // 持有 Viewinit();}@Overridepublic void onClick(View v) {if (v == binding.submitBtn) {iPresenter.submitFromData();} else if (v == binding.clearBtn) {iPresenter.clearData();}}@Overrideprotected void onDestroy() {super.onDestroy();iPresenter.removeHandlerMsgAndCallback();}private void init() {binding.editMsg.setText("normal");binding.edit.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {iPresenter.onDataChanged(s.toString());}@Overridepublic void afterTextChanged(Editable s) {}});binding.submitBtn.setOnClickListener(this);binding.clearBtn.setOnClickListener(this);}@Overridepublic void onDataChangedUpdateText(String data) {binding.editMsg.setText(data);}@Overridepublic void showSubmitFromLoading(String data) {AlertDialog.Builder builder = new AlertDialog.Builder(this);TextView textView = new TextView(this);if (TextUtils.isEmpty(data)) {data = "normal";}textView.setText("正在提交:" + data);builder.setCancelable(false);builder.setView(textView);dialog = builder.show();}@Overridepublic void hideSubmitFromLoading() {dialog.dismiss();}@Overridepublic void clearFromData() {binding.edit.setText("");binding.editMsg.setText("normal");}}

4、IBasePresenter

/*** Base 代理接口 负责业务逻辑*/
public interface IBasePresenter {// 写一些,公用或者通用的方法,用于扩展default void removeHandlerMsgAndCallback() {} // 删除handler 回调和消息}

5、IBaseModel

/*** Base 数据模型接口 负责数据逻辑*/
public interface IBaseModel {// 写一些,公用或者通用的方法,用于扩展default void removeHandlerMsgAndCallback() {} // 删除handler 回调和消息}

6、IBaseView

/*** Base 视图接口 负责视图逻辑*/
public interface IBaseView {// 写一些,公用或者通用的方法,用于扩展default void testBaseView() {}}

7、activity_mvp.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ui.activity.MVPActivity"><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="48dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:background="@color/material_dynamic_primary90"app:title="MVP" /><EditTextandroid:id="@+id/edit"android:layout_width="match_parent"android:layout_height="50dp"android:layout_marginHorizontal="16dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@id/toolbar" /><TextViewandroid:id="@+id/edit_msg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"app:layout_constraintLeft_toLeftOf="@id/edit"app:layout_constraintTop_toBottomOf="@id/edit" /><androidx.appcompat.widget.AppCompatButtonandroid:id="@+id/submit_btn"android:layout_width="match_parent"android:layout_height="58dp"android:layout_marginHorizontal="16dp"android:layout_marginTop="8dp"android:text="submit"android:textAllCaps="false"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@id/edit_msg" /><androidx.appcompat.widget.AppCompatButtonandroid:id="@+id/clear_btn"android:layout_width="match_parent"android:layout_height="58dp"android:layout_marginHorizontal="16dp"android:layout_marginTop="8dp"android:text="clear"android:textAllCaps="false"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@id/submit_btn" /></androidx.constraintlayout.widget.ConstraintLayout>

8、源码地址

GitHub - LanSeLianMa/AndroidMVP: Android MVP 写法

9、其他写法

Android MVC 写法-CSDN博客

Android MVVM 写法-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/231197.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

静态网页设计——跑友原创区(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1AK411x75x/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS 主要内容&am…

全网最细,接口+接口自动化测试面试题汇总(附回答)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、我们测试的接口…

02-微服务-Eureka注册中心

Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 大家思考几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f;有多个user-service实例地址&#xff0c;…

「Vue3面试系列」Vue3 所采用的 Composition Api 与 Vue2 使用的 Options Api 有什么不同?

文章目录 开始之前正文一、Options Api二、Composition Api三、对比逻辑组织Options APICompostion API 逻辑复用 小结 开始之前 Composition API 可以说是Vue3的最大特点&#xff0c;那么为什么要推出Composition Api&#xff0c;解决了什么问题&#xff1f; 通常使用Vue2开…

杨中科 ASP.NETCore开发效率利器 HOT RELOAD

HOT RELOAD 1、困惑:修改了服务器端的代码&#xff0c;必须重新运行程序。 2、方法1: [启动 (不调试) ] 3、方法2: .NET 6开始的Hot Reload(热重载) 正常修改代码后 不重启&#xff0c;是无法看到新的数据展示在页面 修改 运行结果&#xff1a; 方式一&#xff1a;设置开始…

具有大电流,双通道 12V,短地短电源保护等功能的国产芯片GC8549 可替代ONSEMI的LV8548/LV8549

GC8549 可以工作在 3.8~12V 的电源电压上&#xff0c;每 通道能提供高达 1.5A 持续输出电流或者 2.5A 峰值 电流&#xff0c;睡眠模式下功耗小于 1uA。具有 PWM&#xff08;IN/EN&#xff09;输入接口,与行业标 准器件兼容&#xff0c;并具有过温保护&#xff0c;欠压保护&…

使用 PHP-FFMpeg 操作视频/音频文件

做音频合成的时候找到的一个php操作ffmpeg 的类库。GitHub地址&#xff1a;https://github.com/PHP-FFMpeg/PHP-FFMpeg/。本文的例子大部分都是上面的 在使用之前请安装好 FFMpeg 。如何安装&#xff1f;请看 FFmpeg 安装教程。 使用composer快速安装 > composer require …

Vue3-33-路由-路由的别名配置 alias

别名的作用 路由中的别名配置&#xff0c;可以实现 多个路径 对应 同一个路由。 例如 &#xff1a; 路由的路径是 /a; 配置别名为 &#xff1a; /a2; 则 访问 /a 或 /a2 的时候&#xff0c;都可以访问到 同一个组件。 别名的特点 关键字 &#xff1a; alias 当通过别名进行路由…

UE5 C++(十二)— 委托(代理)、多播委托

这里写目录标题 介绍定义声明委托绑定委托执行委托 单播委托多播委托动态多播代理 介绍 这个官网上有很详细介绍&#xff0c;这里介绍几个点 定义 委托 是一种泛型但类型安全的方式&#xff0c;可在C对象上调用成员函数。可使用委托动态绑定到任意对象的成员函数&#xff0c…

爬虫基础一(持续更新)

爬虫概念&#xff1a; 通过编写程序&#xff0c;模拟浏览器上网&#xff0c;然后让其去互联网上抓取数据的过程 分类&#xff1a; 1&#xff0c;通用爬虫&#xff1a;抓取一整张页面数据 2&#xff0c;聚焦爬虫&#xff1a;抓取页面中的局部内容 3&#xff0c;增量式爬虫&…

星穹铁道1.5版本活动【狐斋志异】,有哪些有趣故事和彩蛋

狐斋志异算是玩梗集大成者&#xff0c;加上剧情内补全了一些故事设定。版本活动名称【狐斋志异】致敬的是清朝小说家蒲松龄创作的《聊斋志异》。聊斋志异被国人所熟悉的莫过于里面的鬼怪故事&#xff0c;因此又称为《鬼狐传》。 这次【狐斋志异】开拓任务也是围绕着开拓者去十王…

鸿鹄电子招投标系统:源码级别解析电子招投标的精髓

招投标管理系统是一个集门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理于一体的综合性应用平台。它适用于招标代理、政府采购、企业采购和工程交易等业务的企业&#xff0c;旨在提高项目管理的效率和质量。该系…

Java后端开发——Ajax、jQuery和JSON

Java后端开发——Ajax、jQuery和JSON 概述 Ajax全称是Asynchronous Javascript and XML&#xff0c;即异步的JavaScript和 XML。Ajax是一种Web应用技术&#xff0c;该技术是在JavaScript、DOM、服务器配合下&#xff0c;实现浏览器向服务器发送异步请求。 Ajax异步请求方式不…

Docker中镜像的相关操作

1.辅助操作 docker version&#xff1a;用查看docker客户端引擎和server端引擎版本信息。 docker info&#xff1a;用来查看docker引擎的详细信息。 docker --help&#xff1a;用来查看帮助信息。 2.镜像Image docker images&#xff1a;查看当前本地仓库中存在哪些镜像。 …

速通C语言第十二站 文件操作

系列文章目录 速通C语言系列 速通C语言第一站 一篇博客带你初识C语言 http://t.csdn.cn/N57xl 速通C语言第二站 一篇博客带你搞定分支循环 http://t.csdn.cn/Uwn7W 速通C语言第三站 一篇博客带你搞定函数 http://t.csdn.cn/bfrUM 速通C语言第四站 一篇博客带…

Java重修第一天—学习数组

1. 认识数组 建议1.5倍速学习&#xff0c;并且关闭弹幕。 数组的定义&#xff1a;数组是一个容器&#xff0c;用来存储一批同种类型的数据。 下述图&#xff1a;是生成数字数组和字符串数组。 为什么有了变量还需要定义数组呢&#xff1f;为了解决在某些场景下&#xff0c;变…

ORACLE Primavera Unifier v23.12 最新虚拟机(VM)分享下载

引言 根据上周的计划&#xff0c;我近日简单制作了一个基于ORACLE Primavera Unifier 最新版23.12的虚拟机演示环境&#xff0c;里面包括了unifier的全套系统服务 此虚拟系统环境仅用于演示、培训和测试目的。如要在生产环境中使用此虚拟机&#xff0c;请您与Oracle 销售代表联…

知虾电商(Shopee):东南亚领先电商平台的十大关键特点**

知虾电商&#xff08;Shopee&#xff09;作为东南亚地区领先的电子商务平台&#xff0c;由Sea Group&#xff08;前称Garena&#xff09;在2015年创立。知虾电商以移动优先的策略迅速崛起&#xff0c;为用户提供了一个便捷、安全的在线购物环境。以下是知虾电商的一些关键特点&…

服务器执行rm命令时自动记录到审计日志中

目的 当在服务器上执行类似于 rm 命令时&#xff0c;自动记录该命令执行的时间&#xff0c;在哪里执行的&#xff0c;删除的什么文件&#xff0c;记录到审计日志中&#xff0c;能够查找到某些文件丢失原因 配置 # 需要root权限&#xff0c;sudo不行&#xff0c;这里假设执行…

RocketMQ5-01云原生和AI演变下的架构重构

2022年9月22日&#xff0c;迎来 RocketMQ5 的发版&#xff0c;距离 2017 发布的 4.X 时代&#xff0c;RocketMQ 迎来 5.X 时代。 RocketMQ 4.X 时代已经使众多开发者和项目受益&#xff0c;但是随着关注度、使用量逐步上升以及云原生时代的到来&#xff0c;也对其自身架构带来…