热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

使用kotlin实现MVP的方式(简单好用)

这篇文章主要介绍了使用kotlin实现MVP的方式(简单好用),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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

先定义抽象类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(v: T) {

 open var mView: SoftReference = 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

 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写一个单例是相当的简单,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实现MVP的方式(简单好用)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


推荐阅读
  • 本文通过具体示例详细介绍了 Python 中的装饰器和装饰类的使用方法,包括带参数的装饰器和装饰类的应用场景。 ... [详细]
  • 解决 Pytest 运行时出现 FileNotFoundError 的方法
    在使用 Pytest 进行测试时,可能会遇到 FileNotFoundError 错误,提示无法找到指定的文件或目录。本文将探讨该错误的原因及解决方案。 ... [详细]
  • 在Android应用开发中,当在MenuItem中通过app:actionLayout属性使用Switch控件时,可能会遇到空指针异常的问题。本文将探讨该问题的原因及解决方案。 ... [详细]
  • IEC60825激光产品安全标准详解
    随着激光技术在全球范围内的广泛应用,尤其是激光投影显示技术的兴起,了解和遵守相关的安全标准变得尤为重要。本文将详细介绍IEC60825激光产品安全标准及其重要性。 ... [详细]
  • Mysqlcheck作为MySQL提供的一个实用工具,主要用于数据库表的维护工作,包括检查、分析、修复及优化等操作。本文将详细介绍如何使用Mysqlcheck工具,并提供一些实践建议。 ... [详细]
  • LIN总线技术详解
    LIN(Local Interconnect Network)总线是一种基于UART/SCI(通用异步收发器/串行接口)的低成本串行通信协议,主要用于汽车车身网络中智能传感器和执行器之间的通信。 ... [详细]
  • 本文详细介绍了如何在本地环境中安装配置Frida及其服务器组件,以及如何通过Frida进行基本的应用程序动态分析,包括获取应用版本和加载的类信息。 ... [详细]
  • 在使用KVM虚拟化技术通过NAT模式启动虚拟机时,可能会遇到qemu-ifup-nat脚本执行失败的错误。本文将详细介绍如何诊断和解决这一问题。 ... [详细]
  • 在尝试使用Ubuntu 10.04进行Android开发时,遇到了系统无法识别HTC G1设备的情况。本文将详细介绍如何通过配置系统和安装必要的驱动来解决这一问题。 ... [详细]
  • 本文介绍了Linux内核中TCP的三种接收队列:Prequeue、sk_receive_queue和Backlog。这些队列在数据包处理过程中扮演着重要角色,帮助提高系统性能和效率。 ... [详细]
  • 本文介绍了一种利用空间-光谱总变分模型来有效减少高光谱图像中混合噪声的方法,并提供了详细的Matlab代码实现,旨在为相关领域的研究者提供有价值的参考资料。 ... [详细]
  • 为帮助编程爱好者更好地掌握Python和Go语言的核心技能,我们特别提供两本精选图书的免费赠阅机会。《易懂的Python算法指南》适合所有希望提高算法理解能力的读者,《Go语言编程从入门到精通》则面向对Go语言感兴趣的初学者及有一定基础的开发者。 ... [详细]
  • Redis: 高效的键值存储系统
    Redis是一款遵循BSD许可的开源高性能键值存储系统,它不仅支持多种数据类型的存储,还提供了数据持久化和复制等功能,显著区别于其他键值缓存解决方案。 ... [详细]
  • 第1章选择流程控制语句1.1顺序结构的基本使用1.1.1顺序结构概述是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行 ... [详细]
  • 本文介绍了一个基本的同步Socket程序,演示了如何实现客户端与服务器之间的简单消息传递。此外,文章还概述了Socket的基本工作流程,并计划在未来探讨同步与异步Socket的区别。 ... [详细]
author-avatar
心星Lover
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有