极简易懂得mvp架构模式。

MVP架构模式详解 MVP(Model-View-Presenter)架构通过将应用程序分为三个主要组件,实现了关注点分离,提高了代码的可维护性、可测试性和可读性。它特别适用于需要清晰结构和高测试覆盖率的中大型应用程序。虽然MVP架构存在一些挑战,如代码量增加、学习曲线和潜在的Presenter膨胀问题,但通过遵循最佳实践和合理规划,这些问题可以得到有效缓解。随着技术的发展,MVP也在不断演进,与新的技术和模式结合,继续发挥其价值。 阅读详情

刚开始对mvp的架构模式很模糊,而且也有很多文章对mvp模式的介绍,说实话,看了那么多知道的都是一些文字上的东西。真的需要手动实际去操作,才能真正领悟mvp的极度舒适的感觉。

话不多说,首先我们做一个登录的简单例子。

首先是布局:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:textSize="20sp"
            android:textColor="#000000"
            android:text="用户名:"
            android:layout_width="100dp"
            android:layout_height="wrap_content" />

        <EditText
            android:id="@+id/et_username"
            android:hint="请输入用户名"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>



    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:textSize="20sp"
            android:textColor="#000000"
            android:text="密码:"
            android:layout_width="100dp"
            android:layout_height="wrap_content" />

        <EditText
            android:id="@+id/et_passworld"
            android:hint="请输入用户名"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>



    <LinearLayout
        android:gravity="center"
        android:layout_gravity="center"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/btn_sure"
            android:gravity="center"
            android:layout_gravity="center"
            android:text="login"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />


        <Button
            android:id="@+id/btn_cancle"
            android:gravity="center"
            android:layout_gravity="center"
            android:text="clear"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />

    </LinearLayout>


    <ProgressBar
        android:visibility="gone"
        android:id="@+id/pb_loading"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

然后我们从布局中可以看到,其实主要就是俩个功能,1 登录 2 清空。

然后首先我们先写bean类:

public class User {
    private String userName;
    private String passWord;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
}

然后presenter和moudle之间也是通过接口进行交互的。

所以写一个接口,用于之后的操作:

public interface IUser {
    public void login(String userNmae,String passWorld,LogInListener logInListener);
}

然后这里需要我们一个监听的回调:

public interface LogInListener {
    void loginSucceed(User user);
    void loginFaile();
}

然后是我们的presenter:

public class UserPresenter implements IUser {
    @Override
    public void login(final String userNmae, final String passWorld, final LogInListener logInListener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (TextUtils.equals(userNmae,"pw") && TextUtils.equals(passWorld,"123")){
                    User user = new User();
                    user.setUserName(userNmae);
                    user.setPassWord(passWorld);
                    logInListener.loginSucceed(user);
                }else {
                    logInListener.loginFaile();
                }
            }
        }).start();
    }
}

然后是我们的presenter和view之间的接口:

public interface IloginView {
    String getUserName();
    String getPassWorld();
    void clearUserName();
    void clearPassWorld();
    void toMainActivity(User user);
    void showFaileToast();
    void showLoading();
    void hideLoading();
}

然后就是我们的逻辑操作了:

public class UserPresenterManager {
    private final IloginView loginView;
    private final UserPresenter userPresenter;
    private Handler mHandler = new Handler();
    public UserPresenterManager(IloginView iloginView) {
        this.loginView = iloginView;
        this.userPresenter = new UserPresenter();
    }
    public void login(){
        loginView.showLoading();
        userPresenter.login(loginView.getUserName(), loginView.getPassWorld(), new LogInListener() {
            @Override
            public void loginSucceed(final User user) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        loginView.toMainActivity(user);
                        loginView.hideLoading();
                    }
                });
            }

            @Override
            public void loginFaile() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        loginView.showFaileToast();
                        loginView.hideLoading();
                    }
                });
            }
        });
    }

    public void clear() {
        loginView.clearUserName();
        loginView.clearPassWorld();
    }

}

然后是我们的view:

public class MainActivity extends AppCompatActivity implements IloginView{
    private EditText et_userName;
    private EditText et_userPassWorld;
    private Button btn_sure;
    private Button btn_cancle;
    private ProgressBar pb_loading;
    private UserPresenterManager loginPresenter = new UserPresenterManager(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private void initViews() {
        et_userName = findViewById(R.id.et_username);
        et_userPassWorld = findViewById(R.id.et_passworld);
        pb_loading = findViewById(R.id.pb_loading);
        btn_sure = findViewById(R.id.btn_sure);
        btn_cancle = findViewById(R.id.btn_cancle);
        btn_sure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginPresenter.login();
            }
        });

        btn_cancle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginPresenter.clear();
            }
        });
    }


    @Override
    public String getUserName() {
        return et_userName.getText().toString() == null ? "" : et_userName.getText().toString();
    }

    @Override
    public String getPassWorld() {
        return et_userPassWorld.getText().toString() == null ? "" : et_userPassWorld.getText().toString();
    }

    @Override
    public void clearUserName() {
        et_userName.setText("");
    }

    @Override
    public void clearPassWorld() {
        et_userPassWorld.setText("");
    }

    @Override
    public void toMainActivity(User user) {
        Toast.makeText(this, "succeed:"+"userName="+user.getUserName(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showFaileToast() {
        Toast.makeText(this, "faile", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showLoading() {
        pb_loading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        pb_loading.setVisibility(View.GONE);
    }
}

ok,完美了。

三种架构模式——MVC、MVP、MVVM MV系列框架中,M和V分别指Model层和View层,但其功能会因为框架的不同而变化。Model层是数据模型,用来存储数据;View层是视图,展示Model层的数据。虽然在不同的框架中,Model层和View层的内容可能会有所差别,但是其基础功能不变,变的只是数据的传输方式 。本文讲解MVC、MVP和MVVM三种架构模式。 阅读详情

相关推荐

Android 开发中的架构模式(1) -- MVC / MVP / MVVM

Android 开发中的架构模式 -- MVC / MVP / MVVM

u013083465的专栏 1217

MVP架构模式

什么是MVP架构MVP(Model-View-Presenter)是从经典的模式MVC演变而来的,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有

小北的博客 959

Android 架构模式 MVC、MVP、MVVM、MVI

理想状态 Activity / Fragment 是只处理表现逻辑的部分 ,但现实是 Activity 天然不可避免要处理 UI,也要处理用户交互,说明 Activity 本身天然承担了 View 的角色。那么这个架构就会造成 Activity 里糅合了视图和业务的代码,分离程度不够。对可预测性和可调试性要求极高的项目,与 Jetpack Compose 高度契合。小型项目,功能非常少、UI逻辑简单的页面。中大型项目,结构清晰,易于模块化和维护。

随手纪念的博客 1027

谈谈对MVP框架模式的理解(工作总结)

工作几年,发现代码写的越久,写代码前考虑的东西越多,越小心也越慢了。如果之前总是20%编码时间需要80%时间来debug和维护,那现在当然希望debug所占的时间越少越好,在编码之前更多的构思和设计,尽可能规避可能出现的问题。 不知道从什么时候开始,项目进度总是在拖着我们往前疯狂地写需求,打补丁,当脏代码越来越多,结构越来越臃肿,我们开始想起来一个叫架构的东西。然后又开始计划重构代码,甚至重新设计框架,可惜一堆接一堆的新bug等着去解,重构计划一拖再拖,似乎这才是该做的事情,慢慢忘记了软件里那些真正绚丽的

Ctrlturtle的博客 7239

安卓MVP框架模式demo

该MVP框架模式demo主要展现MVP框架的基本原理,且使用泛型使得Presenter可以动态绑定和解绑View层接口对象,能让你快速理解MVP的工作原理。

Mvp项目架构

利用Retrofit,RxJava,Okhttp搭建的一个Mvp模式的项目,可以在此基础上进行快速开发

MVP架构

MVP架构 1、MVP概述 ​ MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。 ​ 优势: View与Model完全隔离 Presenter与View的具体实现技术无关 可以进行View的模拟测试 缺点: MVP的明显缺点是增加了代码的复杂度,特别是针对小型Android应用的开发,会使程序冗余。 还有大量的View->Model,Model->View的手动同步逻辑,会导致Prese

qq_41684070的博客 5384

CentOS 7下Multipath多路径存储的实战配置与性能优化

本文详细介绍了在CentOS 7系统中配置与优化Multipath多路径存储的完整实战流程。从安装部署、核心配置文件解读,到性能调优与生产环境避坑指南,全面解析如何利用Device Mapper Multipath构建高可用、负载均衡的存储链路,提升存储系统可靠性与I/O性能。

weixin_29278805的博客 320

细谈MVP架构模式

什么是MVP架构?: MVP就是Model-View-Presenter,MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方: Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个 重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Cont

Kiven 每天都需要有所获,每天都需要进步......... 3007

FPGA开发者必看:手把手教你用Xilinx ERNIC IP实现RoCE v2网络加速(附PG332文档解读)

本文详细解析了Xilinx ERNIC IP在FPGA平台上实现RoCE v2网络加速的全流程,包括架构设计、Vivado工程配置、驱动开发与性能调优。通过PG332技术文档的实践指导,帮助开发者快速构建低延迟、高性能的网络加速方案,适用于数据中心和边缘计算场景。

weixin_29168813的博客 670

DDS信号发生器设计避坑指南:从AD9834配置到巴特沃斯滤波实战

本文详细解析了基于AD9834芯片的DDS信号发生器设计中的关键技术要点与常见陷阱,涵盖时钟源选择、寄存器配置时序、巴特沃斯滤波器设计等核心内容。针对中高频段信号质量优化,提供了实用的解决方案和代码示例,帮助工程师规避设计误区,提升信号发生器的性能和稳定性。

2y3u4i5o6p的博客 782

一文形象生动地让你理解什么是MVP架构模式,看不懂你砍我

前言 本文将会以讲故事的形式加深理解。 在Android传统模式开发中,随着Activity的功能增多,其代码也在不断增加。那么我们很可能会发现,如果我们再要往Activity里边加一个功能,而恰好这个功能又要读数据库又要请求Http, 爆炸!加这么个功能要1000行代码(夸张),那么我们的Activity的代码就会变得十分臃肿,你没法快速地完成一个功能代码的修改。 因此,MVP架构模式正是解决这...

星河Dac 7973

Lama:基于傅立叶卷积的分辨率鲁棒性大掩模修复

为了缓解修复网络和损失函数都缺乏有效的感受野这个问题,提出了大掩模修复(LaMa)。LaMa基于一种新的修复网络架构,该架构使用快速傅立叶卷积(FFC),具有图像范围的感受野;高感受野感知损失;大型训练掩码,释放前两个组件的潜力。

qq_44926214的博客 1418

Android 架构模式之 MVP

在 MVP 架构中,Activity 就全心的处理着和 View 相关的事情,Model 负责处理数据请求,替 Presenter 分担了很大一部分负担,这里特意新增了一个 CacheRepository 来体现提取 Model 层的用意,这样就可以在 Model 层进行不同渠道的分发,既体现了单一职责原则,又很好的提高了代码的可读性。其次,由于 View 会只有 Presenter 引用,Presenter 持有 View 和 Model 的引用,如果处理不当,也会存在内存泄漏/空指针的风险。

villen_t的博客 1887

【光子 AI】AI Agent 知识体系深度研究报告

从理论基础到前沿应用:全面解析人工智能代理的核心架构、关键技术与发展趋势📅 2026 年 3 月 | 📊 深度研究报告 | 🔬 人工智能领域 | 📈 前沿技术分析**AI Agent(人工智能代理)**是一种能够感知环境、基于所获得的信息做出决策,并执行行动以影响该环境的软件系统。AI Agent 的设计旨在模仿或实现智能行为,它们可以在各种环境中操作,包括物理世界和虚拟空间。随着大语言模型(LLM)技术的突破性进展,AI Agent 正从实验室研究快速走向产业应用。根据 Gartner 发布的《2

AI天才研究院 179

Python爬虫实战:利用最新技术高效爬取百度贴吧帖子内容

本文将详细介绍如何使用Python最新技术栈构建一个高效的百度贴吧爬虫,包括requests-html异步请求、BeautifulSoup4解析、数据存储到MongoDB以及应对反爬机制等完整解决方案。文章包含5000余字详细教程和完整代码实现。网络爬虫(Web Crawler)是一种自动获取网页内容的程序,广泛应用于搜索引擎、数据分析和内容聚合等领域。Python凭借其丰富的库生态系统成为爬虫开发的首选语言。贴吧作为中文互联网最大的兴趣社区,包含大量有价值的UGC内容。动态加载内容处理登录状态维持。

2201_76125261的博客 541

MVP.css终极指南:5分钟构建专业网页的极简CSS框架

MVP.css是一款革命性的极简CSS框架,专为追求效率和简洁的开发者设计。这个无类CSS框架通过直接为HTML元素提供开箱即用的样式,让您无需学习任何新的CSS框架或命名约定。在短短5分钟内,您就能构建出专业级的网页界面,享受快速原型开发的乐趣。 ## 为什么选择MVP.css?快速上手的极简CSS解决方案 MVP.css的核心优势在于其极简主义哲学。与传统的CSS框架不同,MVP.css不

gitblog_01160的博客 822

从零学懂车载 TSN(二):802.1AS、Qbv、Qbu 是如何让 Ethernet “按时发送”的?

假设有两台设备: ECU A 认为: 但 Switch B 认为: 如果我们规定: 问题就来了。ECU:Switch:整个调度立即失效。因此 TSN 要做时间调度,第一件事就是:这就是:IEEE 802.1AS 定义时间敏感网络里的:工程中通常会看到:gPTP也就是:generalized Precision Time Protocol可以先简单理解成: 核心表达:所有 TSN 节点使用共同时间。后面抓包时你会经常遇到: 刚入门时不用急着研究每个 bit。先搞清楚它们解决什么问题。两个设备连接: A 需要知

struggle_22_58的博客 50

【Android】MVP架构模式

首先,为了保证Presenter与View和Model的解耦,我们需要为View和Model定义接口。

2302_79323248的博客 1102

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Android MVP 架构模式详解

MVP Sample MVP架构模式入门案例,在众多案例中,应该算是比较规范和容易理解的案例了。(请无视我的自恋)示例代码请到我的github下载: https://github.com/dance609195946/MVPSample MVP架构模式详解 概念解释 MVP是Model(数据) View(界面) Presenter(表现层)的缩写,它是MVC架构的变种,强调Model和View

潜移默化... 4097

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

小议MVC、MVP、MVVP架构模式

  架构模式从来都是为了解决问题而生的,Android里的MVC Model和View耦合,出现了MVP,又因为activity与实际界面与presenter耦合出现了想将view与activity降低耦合的MVVP,或者其他架构模式。 目录 用 [TOC]来生成目录: 目录 MVC MVP MVVP MVC 观察者模式最初始的模块归类模型   M...

梦江月 2535

浅谈mvp架构模式

浅谈mvp架构模式MVP架构 MVP是 model,view,presenter的缩写,分别代表着数据,视图和发布层。mvp的前身是mvc,他和mvc最显著的区别在于mvp中的view层不直接与model通信,所有的通信交流都发生在presenter上。在传统的Model View Controller(MVC)中,我们将所有的业务逻辑放入Controller中,这样导致Controlle

Ahri_JIN的博客 740

极简 MVP 本地环境:一个命令启动必要服务

极简 MVP 的本地环境只启动完成核心任务所需的服务。锁定工具版本、提供样例数据和健康检查后,一条命令就能暴露真正缺失的依赖。

weixin_63764436的博客 4948
上一篇: 处理Edittext限制字数提示,以及回车换行功能。
下一篇: butterknife的使用,以及点击右键没有提示。
green-Fir
博客等级 码龄9年 15粉丝 72原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值