用kotlin实现MVP,简单好用

kotlin怎么好用就不多说了,总之我用了感觉非常舒服,今天说一下用kotlin搭建一个MVP框架。

用kotlin实现MVP,简单好用_第1张图片


先定义抽象类IPresenter,IPresenter持有软引用定义的mView,防止内存泄漏,mView类型必须是实现了IView接口的实例,然后定义生命周期方法,open并且不是抽象方法,让子类有选择的去实现生命周期。

package com.khaless.demo.mvp

import android.content.Intent
import android.os.Bundle
import java.lang.ref.SoftReference


/**
 * Author: Li Hai Kun
 * Description:
 * Date: 2017/3/22
 */
abstract class IPresenter<T : IView>(v: T) {

    open var mView: SoftReference<T> = SoftReference(v)

    open fun onCreate(intent: Intent?) {
        mView.get()?.initView()
    }

    open fun onStart() {}
    open fun onResume() {}
    open fun onPause() {}
    open fun onStop() {}
    open fun onDestroy() {}
    open fun onCreateView(arguments: Bundle?) {}

}


定义IView接口,持有一个mPresenter属于上面定义的IPresenter类型,这个mPresenter就是实现IView接口实例的Presenter层具体实例,因为kotlin可以在接口定义属性,实现接口的实例必须给mPresenter赋值。然后放一些共用的方法,比如弹出对话框,toast之类的

package com.khaless.demo.mvp

import android.content.Context
import android.widget.Toast

/**
 * Author: Li Hai Kun
 * Description:
 * Date: 2017/6/2
 */
interface IView {

    val mPresenter: IPresenter<out IView>

    fun initView()

    fun showProgressDialog(){

    }

    fun dismissProgressDialog(){

    }

    fun showToast(text:String,context: Context,time:Int=Toast.LENGTH_SHORT){
        Toast.makeText(context,text,time).show()
    }


}


一个Base类,用一个set记录当前View层所有的Presenter,这样做的好处就是有些复杂的页面可以放多个presenter。在onCreate方法里获取调用addPresenters()方法获取所有presenter,默认把定义的mPresenter添加,如果有多个的话可以在具体实现类重写这个方法。然后就是调用每一个生命周期方法。最后可以根据实际情况实现IView定义的一些共用方法,比如对话框弹出。

 
  
package com.khaless.demo.mvp

import android.app.Activity
import android.os.Bundle
import java.util.*


/**
 * Author: Li Hai Kun
 * Description:
 * Date: 2017/6/2
 */
abstract class BaseActivity: Activity(), IView {

    private val mAllPresenters = HashSet>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutId())
        addPresenters()
        mAllPresenters.forEach { it.onCreate(intent) }
    }

    open fun getPresenters():MutableList>{
        return mutableListOf(mPresenter)
    }

    private fun addPresenters() {
        getPresenters().forEach { mAllPresenters.add(it)}
    }

    override fun onStart() {
        super.onStart()
        mAllPresenters.forEach { it.onStart() }
    }

    override fun onResume() {
        super.onResume()
        mAllPresenters.forEach { it.onResume() }
    }

    override fun onPause() {
        super.onPause()
        mAllPresenters.forEach { it.onPause() }
    }

    override fun onStop() {
        super.onStop()
        mAllPresenters.forEach { it.onStop() }
    }

    override fun onDestroy() {
        super.onDestroy()
        mAllPresenters.forEach { it.onDestroy() }
    }

    abstract fun getLayoutId():Int

    override fun showProgressDialog() {
        super.showProgressDialog()
    }

    override fun dismissProgressDialog() {
        super.dismissProgressDialog()
    }

}


接着就是具体实现,假设有一个需求,view层点击添加用户按钮,presenter层将当前输入的用户信息做校验或者是一些其他操作,然后调用model层实现添加用户的操作,model层完成后将结果告诉presenter层,最后presenter层将具体结果显示在view层,在添加的过程中可能需要view层转个菊花什么的提示正在添加用户。

首先是model层,model层主要是做一些具体的操作:

用kotlin实现MVP,简单好用_第2张图片

用单例实现,而kotlin写一个单例是相当的简单,object即可。一个添加用户的方法,最后一个参数传递一个lambda表达式,用于通知presenter操作结果。表达式作为最后一个参数的写法我非常喜欢,一个是不用像JAVA那样定义一个接口,然后再回调,再一个是调用的地方后面加一个大括号即可。



接着是P层,首先定义UserContract,定义这个模块view层和presenter层的抽象方法

package com.khaless.demo.presenter

import com.khaless.demo.mvp.IView


/**
 * Author: Li Hai Kun
 * Description:
 * Date: 2018/3/23
 */
interface UserContract {

    interface IUserView : IView {
        fun showAddUserResult(boolean: Boolean)
    }


    interface IUserPresenter{
        fun addUser(name:String)
    }

}

然后就是presenter具体实现,实现抽象接口的方法

package com.khaless.demo.presenter

import android.text.TextUtils
import com.khaless.demo.model.UserModel
import com.khaless.demo.mvp.IPresenter

/**
 * Author: Li Hai Kun
 * Description:
 * Date: 2018/7/13 0013
 */
class UserPresenter(view: UserContract.IUserView):UserContract.IUserPresenter,
        IPresenter(view) {

    override fun addUser(name: String) {

        //弹出对话框
        mView.get()?.showProgressDialog()

        //做一些校验
        if (!TextUtils.isEmpty(name)){
            UserModel.addUser(name) {
                //关闭对话框并显示结果
                mView.get()?.dismissProgressDialog()
                mView.get()?.showAddUserResult(it)
            }
        }
    }
}

 最后就是view层的具体实现

package com.khaless.demo.view

import com.khaless.demo.R
import com.khaless.demo.mvp.BaseActivity
import com.khaless.demo.presenter.UserContract
import com.khaless.demo.presenter.UserPresenter
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity: BaseActivity(),UserContract.IUserView {


    override val mPresenter: UserPresenter= UserPresenter(this)

    override fun getLayoutId(): Int = R.layout.activity_main

    override fun initView() {
        tvUser.setOnClickListener {
            mPresenter.addUser("卡丽熙")
        }
    }



    override fun showAddUserResult(boolean: Boolean) {
        if (boolean){
            tvUser.text = "添加用户成功"
        }else{
            tvUser.text = "添加用户失败"

        }
    }
}


比较简单,但是大概这就是MVP模式的主要结构了

你可能感兴趣的:(Kotlin,for,Android)