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接口

java 复制代码
/**
 * 代理接口 负责业务逻辑
 */
public interface IPresenter extends IBasePresenter {

    void setView(IView view);  // 持有 View

    void setModel(IModel model);  // 持有 Model


    void onDataChanged(String data); // 时时修改Model的数据,由View通知 Presenter

    void onDataChangedUpdateText(String data); // 修改View的TextView数据,由Model通知 Presenter


    void submitFromData(); // 执行Model的 提交表单服务,由View通知 Presenter


    void showSubmitFromLoading(String data); // 执行View的显示loading方法,由Model通知 Presenter

    void hideSubmitFromLoading(); // 执行View的隐藏loading方法,由Model通知 Presenter


    void clearData(); // 执行Model的 清空数据方法,由View通知 Presenter

    void clearTextData(); // 执行View的清空TextView内容方法,由Model通知 Presenter

}

1.1、实现IPresenter接口

java 复制代码
/**
 * 具体业务逻辑实现
 */
public class IPresenterImp implements IPresenter {

    private IView view;
    private IModel model;

    @Override
    public void setView(IView view) {
        this.view = view;
    }

    @Override
    public void removeHandlerMsgAndCallback() {
        model.removeHandlerMsgAndCallback();
    }

    @Override
    public void setModel(IModel model) {
        this.model = model;
    }

    @Override
    public void onDataChanged(String data) {
        model.onDataChanged(data);
    }

    @Override
    public void onDataChangedUpdateText(String data) {
        view.onDataChangedUpdateText(data);
    }

    @Override
    public void submitFromData() {
        model.submitFromData();
    }

    @Override
    public void showSubmitFromLoading(String data) {
        view.showSubmitFromLoading(data);
    }

    @Override
    public void hideSubmitFromLoading() {
        view.hideSubmitFromLoading();
    }

    @Override
    public void clearData() {
        model.clearData();
    }

    @Override
    public void clearTextData() {
        view.clearFromData();
    }

}

2、定义Model接口

java 复制代码
/**
 * 数据模型接口 负责数据逻辑
 */
public interface IModel extends IBaseModel {

    default void setPresenter(IPresenter presenter) {}  // 持有 Presenter

    /**
     * 这些都是方法,都是由 Presenter 调用的
     */

    void onDataChanged(String data); // 监听文本变化,时时更新数据

    void submitFromData(); // 提交表单数据

    void clearData(); // 清空数据

}

2.1、实现Model接口

java 复制代码
/**
 * 数据模型逻辑 具体实现
 */
public class IModelImp implements IModel {

    private String mData = "";
    private IPresenter presenter;
    private Handler handler = new Handler();

    @Override
    public void setPresenter(IPresenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public void onDataChanged(String data) {
        mData = data;
        presenter.onDataChangedUpdateText(mData);
    }

    @Override
    public void removeHandlerMsgAndCallback() {
        handler.removeCallbacksAndMessages(null);
    }

    @Override
    public void submitFromData() {
        presenter.showSubmitFromLoading(mData);
        handler.removeCallbacksAndMessages(null);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                presenter.hideSubmitFromLoading();
            }
        }, 1500);
    }

    @Override
    public void clearData() {
        mData = "";
        presenter.clearTextData();
    }
}

3、定义View接口

java 复制代码
/**
 * 视图接口 负责视图逻辑
 */
public interface IView extends IBaseView {

    default void setPresenter(IPresenter presenter) {} // 持有 Presenter

    /**
     * 这些都是方法,都是由 Presenter 调用的
     */

    void onDataChangedUpdateText(String data); // 根据时时数据更新TextView

    void showSubmitFromLoading(String data); // 显示提交表单loading

    void hideSubmitFromLoading(); // 隐藏提交表单loading

    void clearFromData(); // 清空EditText数据

}

3.1、实现View接口

java 复制代码
/**
 * 视图逻辑 具体实现
 */
public class MVPActivity extends AppCompatActivity implements IView, View.OnClickListener {

    private ActivityMvpBinding binding;
    private IModel iModel;
    private IPresenter iPresenter;
    private AlertDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMvpBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        iPresenter = new IPresenterImp();
        iModel = new IModelImp();

        // 注意一下,写的顺序

        iModel.setPresenter(iPresenter); // 持有 Presenter
        setPresenter(iPresenter); // 持有 Presenter

        iPresenter.setModel(iModel); // 持有 Model
        iPresenter.setView(this); // 持有 View

        init();
    }

    @Override
    public void onClick(View v) {
        if (v == binding.submitBtn) {
            iPresenter.submitFromData();
        } else if (v == binding.clearBtn) {
            iPresenter.clearData();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        iPresenter.removeHandlerMsgAndCallback();
    }

    private void init() {
        binding.editMsg.setText("normal");
        binding.edit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                iPresenter.onDataChanged(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
        binding.submitBtn.setOnClickListener(this);
        binding.clearBtn.setOnClickListener(this);
    }

    @Override
    public void onDataChangedUpdateText(String data) {
        binding.editMsg.setText(data);
    }

    @Override
    public 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();
    }

    @Override
    public void hideSubmitFromLoading() {
        dialog.dismiss();
    }

    @Override
    public void clearFromData() {
        binding.edit.setText("");
        binding.editMsg.setText("normal");
    }

}

4、IBasePresenter

java 复制代码
/**
 * Base 代理接口 负责业务逻辑
 */
public interface IBasePresenter {

    // 写一些,公用或者通用的方法,用于扩展

    default void removeHandlerMsgAndCallback() {} // 删除handler 回调和消息

}

5、IBaseModel

java 复制代码
/**
 * Base 数据模型接口 负责数据逻辑
 */
public interface IBaseModel {

    // 写一些,公用或者通用的方法,用于扩展

    default void removeHandlerMsgAndCallback() {} // 删除handler 回调和消息

}

6、IBaseView

java 复制代码
/**
 * Base 视图接口 负责视图逻辑
 */
public interface IBaseView {

    // 写一些,公用或者通用的方法,用于扩展

    default void testBaseView() {}

}

7、activity_mvp.xml

java 复制代码
<?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.Toolbar
        android: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" />

    <EditText
        android: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" />

    <TextView
        android: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.AppCompatButton
        android: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.AppCompatButton
        android: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博客

相关推荐
crmscs40 分钟前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob43 分钟前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔1 小时前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei9961 小时前
flutter和Android动画的对比
android·flutter·动画
lxysbly3 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首3 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19436 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs6 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&6 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
LDORntKQH6 小时前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android