使用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的方式(简单好用)就是小编分享给大家的全部内容了,希望能给大家一个参考。
- python爬虫常用库之requests详解
- python爬虫常用库之urllib详解
- 如何 build 出尽可能小的 docker image?
- 一步一步教你如何用python操作mysql
- 利用Python实现卷积神经网络的可视化
- SDP(13): Scala.Future - far from completion,绝不能用来做甩手掌柜
- 干货|浅谈强化学习的方法及学习路线
- 如何实时查看Docker容器占用的CPU、内存状态?
- [安全] mysqldump 备份的后门
- Elasticsearch 快速起步
- Mysql 高一致性复制结构
- Scrapy中如何提高数据的插入速度
- python基础语法(1)
- Python基础语法(2)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- springBoot 入门(一)—— 使用idea创建第一个springBoot项目
- “dddb超级”工具包——高效、快速开发JavaWeb项目后端结构
- 在Java Web中设计的编解码
- 怎么让用一行代码实现页面的定时强制刷新?脚本刷流量再也不用愁了!
- 什么是Javac
- springBoot 入门(二)—— 使用 spring.profiles.active来区分配置
- Kubernetes 1.19.0——deployment(2)
- JavaWeb新手进阶经典项目 & 半小时高效开发 & 海量知识点涵盖 (二)
- Java web 开发 Session超时设置
- JavaWeb第四讲 会话跟踪技术HttpSession、Cookie、url、隐藏表单域
- springBoot 入门(三)—— 使用 RestController
- SSM第一讲 Spring概述和基础知识详解
- springBoot 入门(四)—— 使用 纯注解方式的junit整合测试
- ClassLoader工作机制
- SSM第三讲 SpringAOP开发