使用kotlin實(shí)現(xiàn)MVP的方式(簡(jiǎn)單好用)
kotlin怎么好用就不多說(shuō)了,總之我用了感覺(jué)非常舒服,今天說(shuō)一下用kotlin搭建一個(gè)MVP框架。
先定義抽象類IPresenter,IPresenter持有軟引用定義的mView,防止內(nèi)存泄漏,mView類型必須是實(shí)現(xiàn)了IView接口的實(shí)例,然后定義生命周期方法,open并且不是抽象方法,讓子類有選擇的去實(shí)現(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接口,持有一個(gè)mPresenter屬于上面定義的IPresenter類型,這個(gè)mPresenter就是實(shí)現(xiàn)IView接口實(shí)例的Presenter層具體實(shí)例,因?yàn)閗otlin可以在接口定義屬性,實(shí)現(xiàn)接口的實(shí)例必須給mPresenter賦值。然后放一些共用的方法,比如彈出對(duì)話框,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() } }
一個(gè)Base類,用一個(gè)set記錄當(dāng)前View層所有的Presenter,這樣做的好處就是有些復(fù)雜的頁(yè)面可以放多個(gè)presenter。在onCreate方法里獲取調(diào)用addPresenters()方法獲取所有presenter,默認(rèn)把定義的mPresenter添加,如果有多個(gè)的話可以在具體實(shí)現(xiàn)類重寫(xiě)這個(gè)方法。然后就是調(diào)用每一個(gè)生命周期方法。最后可以根據(jù)實(shí)際情況實(shí)現(xiàn)IView定義的一些共用方法,比如對(duì)話框彈出。
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() } }
接著就是具體實(shí)現(xiàn),假設(shè)有一個(gè)需求,view層點(diǎn)擊添加用戶按鈕,presenter層將當(dāng)前輸入的用戶信息做校驗(yàn)或者是一些其他操作,然后調(diào)用model層實(shí)現(xiàn)添加用戶的操作,model層完成后將結(jié)果告訴presenter層,最后presenter層將具體結(jié)果顯示在view層,在添加的過(guò)程中可能需要view層轉(zhuǎn)個(gè)菊花什么的提示正在添加用戶。
首先是model層,model層主要是做一些具體的操作:
用單例實(shí)現(xiàn),而kotlin寫(xiě)一個(gè)單例是相當(dāng)?shù)暮?jiǎn)單,object即可。一個(gè)添加用戶的方法,最后一個(gè)參數(shù)傳遞一個(gè)lambda表達(dá)式,用于通知presenter操作結(jié)果。表達(dá)式作為最后一個(gè)參數(shù)的寫(xiě)法我非常喜歡,一個(gè)是不用像JAVA那樣定義一個(gè)接口,然后再回調(diào),再一個(gè)是調(diào)用的地方后面加一個(gè)大括號(hào)即可。
接著是P層,首先定義UserContract,定義這個(gè)模塊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具體實(shí)現(xiàn),實(shí)現(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) { //彈出對(duì)話框 mView.get()?.showProgressDialog() //做一些校驗(yàn) if (!TextUtils.isEmpty(name)){ UserModel.addUser(name) { //關(guān)閉對(duì)話框并顯示結(jié)果 mView.get()?.dismissProgressDialog() mView.get()?.showAddUserResult(it) } } } }
最后就是view層的具體實(shí)現(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 = "添加用戶失敗" } } }
比較簡(jiǎn)單,但是大概這就是MVP模式的主要結(jié)構(gòu)了
以上這篇使用kotlin實(shí)現(xiàn)MVP的方式(簡(jiǎn)單好用)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android TextView設(shè)置背景色與邊框的方法詳解
本篇文章是對(duì)Android中TextView設(shè)置背景色與邊框的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android sqlite設(shè)置主鍵自增長(zhǎng)的方法教程
這篇文章主要給大家介紹了關(guān)于Android sqlite設(shè)置主鍵自增長(zhǎng)的方法教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-06-06Android 讀取文件內(nèi)容實(shí)現(xiàn)方法總結(jié)
這篇文章主要介紹了Android 讀取文件內(nèi)容實(shí)現(xiàn)方法的相關(guān)資料,這里提供了幾種方法,大家可以選擇使用,需要的朋友可以參考下2016-10-10Android編程實(shí)現(xiàn)設(shè)置TabHost當(dāng)中字體的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)設(shè)置TabHost當(dāng)中字體的方法,涉及Android針對(duì)TabHost屬性操作的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-12-12Android使用ItemTouchHelper實(shí)現(xiàn)側(cè)滑刪除和拖拽
這篇文章主要為大家詳細(xì)介紹了Android使用ItemTouchHelper實(shí)現(xiàn)側(cè)滑刪除和拖拽,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08