使用kotlin實現(xiàn)MVP的方式(簡單好用)
kotlin怎么好用就不多說了,總之我用了感覺非常舒服,今天說一下用kotlin搭建一個MVP框架。

先定義抽象類IPresenter,IPresenter持有軟引用定義的mView,防止內(nèi)存泄漏,mView類型必須是實現(xiàn)了IView接口的實例,然后定義生命周期方法,open并且不是抽象方法,讓子類有選擇的去實現(xiàn)生命周期。
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就是實現(xiàn)IView接口實例的Presenter層具體實例,因為kotlin可以在接口定義屬性,實現(xiàn)接口的實例必須給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記錄當(dāng)前View層所有的Presenter,這樣做的好處就是有些復(fù)雜的頁面可以放多個presenter。在onCreate方法里獲取調(diào)用addPresenters()方法獲取所有presenter,默認(rèn)把定義的mPresenter添加,如果有多個的話可以在具體實現(xiàn)類重寫這個方法。然后就是調(diào)用每一個生命周期方法。最后可以根據(jù)實際情況實現(xiàn)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<IPresenter<*>>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutId())
addPresenters()
mAllPresenters.forEach { it.onCreate(intent) }
}
open fun getPresenters():MutableList<IPresenter<*>>{
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()
}
}
接著就是具體實現(xiàn),假設(shè)有一個需求,view層點擊添加用戶按鈕,presenter層將當(dāng)前輸入的用戶信息做校驗或者是一些其他操作,然后調(diào)用model層實現(xiàn)添加用戶的操作,model層完成后將結(jié)果告訴presenter層,最后presenter層將具體結(jié)果顯示在view層,在添加的過程中可能需要view層轉(zhuǎn)個菊花什么的提示正在添加用戶。
首先是model層,model層主要是做一些具體的操作:

用單例實現(xiàn),而kotlin寫一個單例是相當(dāng)?shù)暮唵危琽bject即可。一個添加用戶的方法,最后一個參數(shù)傳遞一個lambda表達(dá)式,用于通知presenter操作結(jié)果。表達(dá)式作為最后一個參數(shù)的寫法我非常喜歡,一個是不用像JAVA那樣定義一個接口,然后再回調(diào),再一個是調(diào)用的地方后面加一個大括號即可。
接著是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具體實現(xiàn),實現(xiàn)抽象接口的方法
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<UserContract.IUserView>(view) {
override fun addUser(name: String) {
//彈出對話框
mView.get()?.showProgressDialog()
//做一些校驗
if (!TextUtils.isEmpty(name)){
UserModel.addUser(name) {
//關(guān)閉對話框并顯示結(jié)果
mView.get()?.dismissProgressDialog()
mView.get()?.showAddUserResult(it)
}
}
}
}
最后就是view層的具體實現(xiàn)
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模式的主要結(jié)構(gòu)了
以上這篇使用kotlin實現(xiàn)MVP的方式(簡單好用)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android TextView設(shè)置背景色與邊框的方法詳解
本篇文章是對Android中TextView設(shè)置背景色與邊框的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android sqlite設(shè)置主鍵自增長的方法教程
這篇文章主要給大家介紹了關(guān)于Android sqlite設(shè)置主鍵自增長的方法教程,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06
Android 讀取文件內(nèi)容實現(xiàn)方法總結(jié)
這篇文章主要介紹了Android 讀取文件內(nèi)容實現(xiàn)方法的相關(guān)資料,這里提供了幾種方法,大家可以選擇使用,需要的朋友可以參考下2016-10-10
Android編程實現(xiàn)設(shè)置TabHost當(dāng)中字體的方法
這篇文章主要介紹了Android編程實現(xiàn)設(shè)置TabHost當(dāng)中字體的方法,涉及Android針對TabHost屬性操作的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下2015-12-12
Android使用ItemTouchHelper實現(xiàn)側(cè)滑刪除和拖拽
這篇文章主要為大家詳細(xì)介紹了Android使用ItemTouchHelper實現(xiàn)側(cè)滑刪除和拖拽,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08

