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


推荐阅读
  • 优化 Android 按钮状态下的背景和文本颜色变化
    本文介绍如何通过 Android 的 Selector 实现按钮在不同状态下(如按压)的背景和文本颜色动态变化。我们将详细讲解实现步骤,并提供完整的代码示例。 ... [详细]
  • 本文详细介绍超文本标记语言(HTML)的基本概念与语法结构。HTML是构建网页的核心语言,通过标记标签描述页面内容,帮助开发者创建结构化、语义化的Web页面。 ... [详细]
  • 本文旨在提供一套高效的面试方法,帮助企业在短时间内找到合适的产品经理。虽然观点较为直接,但其方法已被实践证明有效,尤其适用于初创公司和新项目的需求。 ... [详细]
  • 本文介绍了如何通过设置背景形状来轻松地为 Android 的 TextView 添加圆形边框。我们将详细讲解 XML 代码的配置,包括圆角、描边和填充等属性。 ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 解决Anaconda安装TensorFlow时遇到的TensorBoard版本问题
    本文介绍了在使用Anaconda安装TensorFlow时遇到的“Could not find a version that satisfies the requirement tensorboard”错误,并提供详细的解决方案,包括创建虚拟环境和配置PyCharm项目。 ... [详细]
  • 如何将本地Docker镜像推送到阿里云容器镜像服务
    本文详细介绍将本地Docker镜像上传至阿里云容器镜像服务的步骤,包括登录、查看镜像列表、推送镜像以及确认上传结果。通过本文,您将掌握如何高效地管理Docker镜像并将其存储在阿里云的镜像仓库中。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 查找最小值的操作是很简单的,只需要从根节点递归的遍历到左子树节点即可。当遍历到节点的左孩子为NULL时,则这个节点就是树的最小值。上面的树中,从根节点20开始,递归遍历左子 ... [详细]
  • 在使用STM32Cube进行定时器配置时,有时会遇到延时不准的问题。本文探讨了可能导致延时不准确的原因,并提供了解决方法和预防措施。 ... [详细]
  • Netflix利用Druid实现高效实时数据分析
    本文探讨了全球领先的在线娱乐公司Netflix如何通过采用Apache Druid,实现了高效的数据采集、处理和实时分析,从而显著提升了用户体验和业务决策的准确性。文章详细介绍了Netflix在系统架构、数据摄取、管理和查询方面的实践,并展示了Druid在大规模数据处理中的卓越性能。 ... [详细]
  • 深入理解Lucene搜索机制
    本文旨在帮助读者全面掌握Lucene搜索的编写步骤、核心API及其应用。通过详细解析Lucene的基本查询和查询解析器的使用方法,结合架构图和代码示例,带领读者深入了解Lucene搜索的工作流程。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
author-avatar
mobiledu2502887783
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有