kotlin使用mvp框架,以及封装成basemvp

MVP简介

本文使用kotlin代码来写的,在项目中 View 和 Model 并不直接交互,而是使用 Presenter 作为 View 和 Model 之间的桥梁。其中 Presenter 中同时持有 View 层以及 Model 层的 Interface 的引用,而 View 层持有 Presenter 层 Interface 的引用,当 View 层某个页面需要展示某些数据的时候,首先会调用Presenter 层的某个接口,然后 Presenter 层会调用 Model 层请求数据,当 Model 层数据加载成功之后会调用 Presenter 层的回调方法通知 Presenter 层数据加载完毕,最后 Presenter 层再调用 View 层的接口将加载后的数据展示给用户。这就是 MVP 模式的核心过程

这样分层的好处就是大大减少了Model与View层之间的耦合度。一方面可以使得View层和Model层单独开发与测试,互不依赖。另一方面Model层可以封装复用,可以极大的减少代码量。当然,MVP还有其他的一些优点,这里不再赘述。

1、常规的MVP介绍

各个分层的作用

  • Model:负责提供数据(包括从服务端获取,本地获取的数据);
  • View:框架中的视图模块,负责UI展示,UI变更;
  • Presenter:程序中的逻辑模块,负责处理具体事务,逻辑;

Base基类

  • BaseView:用于创建基类View,统一管理view;
  • BasePresenter:所有Presenter层的抽象类,负责Model、View层的引用和销毁;

我们来看看项目结构:
在这里插入图片描述
接下来看看各个类的代码
MainContract

/**
 * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
 */
interface MainContract {
    interface IMainModel {
        fun getDataFromModel(callback: (String?) -> Unit)
    }

    interface IMainView {
        fun showDialog()
        fun updataUI(content: String?)
    }

    interface IMainPresenter {
        fun handlerData()
    }
}

MainActivity

/**
 * MVP 的写法,Version 1: 基础写法
 */
class MainActivity : AppCompatActivity(),
    MainContract.IMainView {

    private var mPresenter: MainPresenter? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mPresenter = MainPresenter(this)
        mPresenter!!.handlerData()
    }

    override fun showDialog() {
        val dialog = ProgressDialog(this)
        dialog.show()
        Handler().postDelayed({ dialog.dismiss() }, 1500)
    }

    override fun updataUI(content: String?) {
        runOnUiThread {
            Toast.makeText(this@MainActivity, "" + content, Toast.LENGTH_SHORT).show()
            tv!!.text = content
        }
    }


}

MainPresenter

/**
 * presenter 层,承担业务逻辑处理,数据源处理等
 */
class MainPresenter(private val mView: MainContract.IMainView?) : MainContract.IMainPresenter {
    private val mModel: MainContract.IMainModel
    init {
        mModel = DataModel()
    }
    override fun handlerData() {
        mView?.showDialog()
        //发起请求,获得回调数据
        mModel.getDataFromModel {
            //经过对数据处理,非空处理,逻辑判断等等,最后更新UI
            mView?.updataUI(it)
        }
    }


}

DataModel

/**
 * model 层,请求网络或数据库,提供数据源(原始数据)
 */
class DataModel : MainContract.IMainModel {
    override fun getDataFromModel(callback: (String?) -> Unit) {
        //此处经过网络请求,获取到数据之后,返回去
        callback("返回数据:123456")
    }
}

activity_main.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=".v1.view.MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

2、封装成baseMvp的模式

关于封装baseMvp,过程有点多,这里就不做详细的介绍,下面来看看项目结构图

在这里插入图片描述
加入一个我自己封装的volley网络请求工具类volleyUtil,用作请求响应的展示。
需要retrofit的同学,可以到我的另外一篇博客里看
最后全部的代码都在这里:https://download.csdn.net/download/wy313622821/12812143

猜你喜欢

转载自blog.csdn.net/wy313622821/article/details/108408176