//基类
/**
* 一、GuardBasePresenter
* abstract抽象类,区别interface,abstract可以有方法实现。
* 传入一个泛型GuardBaseView,内部进行SoftReference(WeakReference),防止循环引用出现内存泄露。
*/
abstract class GuardBasePresenter<V: GuardBaseView>(v: V) {
var mView: SoftReference<V> = SoftReference(v)
//自定义生命周期方法,在GuardBaseActivity调用,达到activity同样的生命周期效果。
fun onCreate() {
mView.get()?.initView()
}
open fun onStart() {}
open fun onResume() {}
open fun onPause() {}
open fun onStop() {}
open fun onDestroy() {}
open fun onCreateView(arguments: Bundle?) {}
}
/**
* 二、GuardBaseView
* interface GuardBaseView内部获得
* 一个val mPresenter: GuardBasePresenter<out GuardBaseView>,Out (协变)将
* 泛型作为内部方法的返回,即mPresenter返回出去可以直接给实现GuardBaseView接口的类使用。
*/
interface GuardBaseView {
val mPresenter: GuardBasePresenter<out GuardBaseView>
//ui创建方法
fun initView()
//自定义通用方法
fun showProgressDialog(){
}
fun dismissProgressDialog(){
}
fun showToast(text:String,context: Context,time:Int=Toast.LENGTH_SHORT){
Toast.makeText(context,text,time).show()
}
}
/**
* 三、GuardBaseActivity
* 在对应生命周期方法中调用GuardBasePresenter自定义生命周期方法,实现效果。
*/
abstract class GuardBaseActivity: Activity(), GuardBaseView {
private val mAllPresenters = HashSet<GuardBasePresenter<*>>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addPresenters()
mAllPresenters.forEach { it.onCreate() }
}
private fun getPresenters():MutableList<GuardBasePresenter<*>> {
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() }
}
override fun showProgressDialog() {
super.showProgressDialog()
}
override fun dismissProgressDialog() {
super.dismissProgressDialog()
}
}
//使用部分
/**
* 四、GuardContract
* 提供mvp组合接口,以便activity中调用。
*/
interface GuardContract {
interface GuardView: GuardBaseView {
fun showResult(text: String)
}
interface GuardPresenter{
fun textClick(id: String)
}
}
/**
* 五、GuardPresenter
* 外部调用GuardPresenter会传入GuardContract.GuardView
* 实现GuardContract.GuardPresenter接口方法
* mView从继承的GuardBasePresenter获得
* 这一句 class GuardPresenter(view: GuardContract.GuardView): GuardContract.GuardPresenter, GuardBasePresenter<GuardContract.GuardView>(view)
* 其中的GuardPresenter(view: GuardContract.GuardView)传入的view提供给
* GuardBasePresenter<GuardContract.GuardView>(view)使用
* GuardBasePresenter必须传入一个view进行软引用,以便提供在activity中使用。
*/
class GuardPresenter(view: GuardContract.GuardView): GuardContract.GuardPresenter, GuardBasePresenter<GuardContract.GuardView>(view) {
override fun textClick(id: String) {
//发送网络请求
GuardModel.requestData(id) {
//得到处理后的数据,通过数据判断,决定调用GuardView哪些接口方法。
//失败则弹出提示
//mView.get()?.showToast(...)
//成功比如设置数据
mView.get()?.showResult(it + "presenter->")
}
}
}
/**
* 六、GuardView,可以独立出来,也可以直接写在activity中。
* anko扩展封装
* lateinit var text: TextView为暴露的控件,方便activity设置值
*/
inline fun ViewManager.guardView() = guardView() {}
inline fun ViewManager.guardView(init: GuardView.() -> Unit): GuardView {
return ankoView({ GuardView(it) },0,init)
}
class GuardView: FrameLayout {
lateinit var text: TextView
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr) {
verticalLayout {
text = textView {
text = "我在guardView中"
}
}
}
}
/**
* 七、GuardActivity
* GuardBaseActivity里面包括GuardBaseView,GuardBaseView里面包括了了GuardBasePresenter
*/
class GuardActivity : GuardBaseActivity(), GuardContract.GuardView {
private lateinit var guardView: GuardView
//创建Presenter。
override val mPresenter: GuardPresenter
get() = GuardPresenter(this)
//通过model获取到的值设置给UI控件。方法来自GuardContract.GuardView
override fun showResult(text: String) {
guardView.text.text = text + "activity实现GuardContract.GuardView的方法"
}
//GuardBaseView方法,创建UI方法。
override fun initView() {
verticalLayout {
guardView = guardView {
onClick { mPresenter.textClick("activity中initView方法内view点击->") }
}
}
}
}
/**
* 八、GuardModel
* 进行数据请求,并且进行数据处理后返回出去,以便Presenter使用。
*/
object GuardModel {
fun requestData(userId: String ,callback: (String) -> Unit) {
callback(userId + "model中数据请求->")
}
}
【kotlin设计与架构】MVP的简单使用
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 原文链接:https://android.jlelse.eu/complete-example-of-testin...