使用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<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就是实现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<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记录当前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<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()
 }

}

接着就是具体实现,假设有一个需求,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<UserContract.IUserView>(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的方式(简单好用)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Kotlin中常见的符号详解

    前几年的Google I/O大会上,Google正式宣布,Kotlin将会成为Android开发的官方支持语言.除了Android外,Kotlin还可以完全作为服务端开发的语言,比如在未来的Spring 5就将对Kotlin提供强大的支持.以及浏览器编程语言,与JS进行交互. Kotlin是一门静态语言,支持多种平台,包括移动端.服务端以及浏览器端,此外,Kotlin还是一门融合了面向对象与函数式编程的语言,支持泛型.安全的空判断,并且Kotlin与Java可以做到完全的交互. 现在介绍Kotl

  • Kotlin中实体类的创建方式

    类的基本格式 class 类名{ } 属性的基本格式 var 属性名字 : 类型 下面是实体类代码 package com.dldw.entity import java.util.* class Demo { //var 声明的属性可以被二次赋值 val声明的是不可变属性,赋值以后不能在赋值,否则编译报错 //长整型 64位 注意后面加大写L var height: Long? = 0L //整型 32 位 var id : Int?= 0 //短整型 16位 var short :Short

  • Kotlin实现在类里面创建main函数

    1.创建在class块外面: class Test{ } /** 我是main入口函数 **/ fun main(args: Array<String>) { var test=Test(); } 这样是一种方式,但是细心的童鞋可能会发现一个问题,目录里面的文件图标是灰色的,而且这种写法看上去怪怪的,有强迫症的可能会接受不了: 2.创建在class里面: class Test{ companion object { /** 我是main入口函数 **/ @JvmStatic fun main(

  • django-利用session机制实现唯一登录的例子

    配置连接数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '数据库名称', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '10.18.62.2', 'PORT': '3306', } } 生成session表 python manage.py makemigrations python manage.py migrate 登录时记住保存用户登录信

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

    kotlin怎么好用就不多说了,总之我用了感觉非常舒服,今天说一下用kotlin搭建一个MVP框架. 先定义抽象类IPresenter,IPresenter持有软引用定义的mView,防止内存泄漏,mView类型必须是实现了IView接口的实例,然后定义生命周期方法,open并且不是抽象方法,让子类有选择的去实现生命周期. package com.khaless.demo.mvp import android.content.Intent import android.os.Bundle imp

  • java读取文件和写入文件的方式(简单实例)

    Java代码 public class ReadFromFile { /** * 以字节为单位读取文件,常用于读二进制文件,如图片.声音.影像等文件. */ public static void readFileByBytes(String fileName) { File file = new File(fileName); InputStream in = null; try { System.out.println("以字节为单位读取文件内容,一次读一个字节:"); // 一次读

  • Ubuntu下安装nvidia显卡驱动(安装方式简单)

    Ubuntu下安装nvidia显卡驱动,用同方法安装过GTX1050,安装成功.不会出现循环登录 第一步 获取显卡型号 想办法获取自己nvidia显卡的型号(一般买电脑的时候都会有显卡型号,我的显卡型号是在电脑上的一个贴纸上),本人的显卡是GTX970M. 第二步 查看GTX970M显卡驱动 去NVDIA driver search page查看支持 GTX970M 显卡的驱动的最新版本的版本号 After a successful search take a note of the resul

  • 利用Kotlin的协程实现简单的异步加载详解

    前言 众所周知在android中当执行程序的耗时超过5秒时就会引发ANR而导致程序崩溃.由于UI的更新操作是在UI主线程进行的,理想状态下每秒展示60帧时人眼感受不到卡顿,1000ms/60帧,即每帧绘制时间不应超过16.67ms.如果某项操作的耗时超过这一数值就会导致UI卡顿.因此在实际的开发中我通常把耗时操作放在一个新的线程中(比如从网络获取数据,从SD卡读取图片等操作),但是呢在android中UI的更新只能在UI主线程中进行更新,因此当我们在非UI线程中执行某些操作的时候想要更新UI就需

  • 详解Java两种方式简单实现:爬取网页并且保存

    对于网络,我一直处于好奇的态度.以前一直想着写个爬虫,但是一拖再拖,懒得实现,感觉这是一个很麻烦的事情,出现个小错误,就要调试很多时间,太浪费时间. 后来一想,既然早早给自己下了保证,就先实现它吧,从简单开始,慢慢增加功能,有时间就实现一个,并且随时优化代码. 下面是我简单实现爬取指定网页,并且保存的简单实现,其实有几种方式可以实现,这里慢慢添加该功能的几种实现方式. UrlConnection爬取实现 package html; import java.io.BufferedReader; i

  • Kotlin 泛型详解及简单实例

     Kotlin 泛型详解 概述 一般类和函数,只能使用具体的类型:要么是基本类型,要么是自定义的类.如果要编写可以应用于多种类型的代码,这种刻板的约束对代码的限制很大.而OOP的多态采用了一种泛化的机制,在SE 5种,Java引用了泛型.泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用

  • Android用MVP实现一个简单的类淘宝订单页面的示例

    MVP(Model-View-Presenter) 是总所周知MVC模式的一个演变,他们的主要目的都是划分模块职责,降低模块耦合,易测试,提高代码复用,网上有很多相关的知识,这里仅是个人看法. 1.层级 Model:负责数据相关的操作 View:负责UI的绘制和用户的交互 Presenter:作为Model和View的中间协调部分,负责两者之间的业务逻辑处理 2.MVP的优缺点 优点:降低耦合,层级职责更明显,易于单元测试 缺点:造成类数量增多,在某些场景下presenter的复用会产生接口冗余

  • tomcat性能优化方式简单整理

    Tomcat本身优化 Tomcat内存优化 启动时告诉JVM我要一块大内存(调优内存是最直接的方式) 我们可以在 tomcat 的启动脚本 catalina.sh 中设置 java_OPTS 参数 JAVA_OPTS参数说明 server 启用jdk 的 server 版 Xms java虚拟机初始化时的最小内存 Xmx java虚拟机可使用的最大内存 XX: PermSize 内存永久保留区域 XX:MaxPermSize 内存最大永久保留区域 配置示例: JAVA_OPTS='-Xms102

  • Python实现定时执行任务的三种方式简单示例

    本文实例讲述了Python实现定时执行任务的三种方式.分享给大家供大家参考,具体如下: 1.定时任务代码 #!/user/bin/env python # @Time :2018/6/7 16:31 # @Author :PGIDYSQ #@File :PerformTaskTimer.py #定时执行任务命令 import time,os,sched schedule = sched.scheduler(time.time,time.sleep) def perform_command(cmd

  • 浅析MVP模式中V-P交互问题及案例分享

    在差不多两年的时间内,我们项目组几十来号人都扑在一个项目上面.这是一个基于微软SCSF(Smart Client Software Factory)的项目,客户端是墨尔本一家事业单位.前两周,我奉命负责对某个模块进行Code Review工作,在此期间,发现了一些问题,也有了一些想法.不过,有些想法可能还不是很成熟,不能完全保证其正确性,有机会写出来讨论一下.今天来说说关于MVP的一些想法. 一.简单讲讲MVP是什么玩意儿如果从层次关系来讲,MVP属于Presentation层的设计模式.对于一

随机推荐