Kotlin的魔能机甲——KtArmor(三)
前言
继上篇说到, KtArmor-MVP的插件使用。我们可以快速创建基本的模板代码,但是在编写业务代码时候,不熟悉KtArmor-MVP框架, 不知其然,无法驾驭这个魔能机甲
。所以这篇我先从BaseActivity 开始说起,介绍KtArmor—MVP 的用法,“深入源码”
解析,带你走进 KtArmor-MVP。
Activity
KtArmor-MVP 框架主要包含3个主要的Activity
- BaseActivity
- ToolbarActivity
- MvpActivity
它们之间继承关系如下:
MvpActivity > ToolbarActivity > BaseActivity
然后我们来看看他们具体的实现
BaseActivity
abstract class BaseActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 在界面未初始化之前调用的初始化窗口initWidows()if (initArgs(intent.extras)) {setContentView(getLayoutId())initBefore()initView()initListener()initData()} else {finish()}}open fun initArgs(bundle: Bundle?): Boolean = trueopen fun initWidows() {}abstract fun getLayoutId(): Intopen fun initBefore() {}open fun initView() {}open fun initListener() {}open fun initData() {}
}
复制代码
BaseActivity
基本的模板结构,定义了基本的Activity 初始化的方法。可以继承BaseActivity,复写对应方法进行扩展。下面是方法具体描述:
initWidows
: 在界面(setContentView
)未初始化之前调用的初始化窗口方法initArgs
: 初始化界面参数方法(Activity 之间跳转传递参数), 该方法 默认返回True
, 显示Activity, 否则返回False, 不显示Activity。getLayoutId
:初始化 Activity 的 layout 布局initBefore
:initView()
之前,setContentView()
方法 之后的初始化方法。initView
:初始化控件view 方法.initListener
:初始化 控件view 相关 listener 方法。initData
:初始化数据方法
可以适用于
APP 启动页面
,简单展示页面
等, 不涉及到Presenter 的Activity
ToolbarActivity
abstract class ToolbarActivity : BaseActivity() {var toolbarTitle: String = ""set(value) {field = valuesupportActionBar?.title = value}override fun initView() {super.initView()initToolbar()}/*** Toolbar id must be toolbar*/private fun initToolbar() {findViewById<Toolbar>(R.id.toolbar)?.let { toolbar ->setSupportActionBar(toolbar)supportActionBar?.let {it.setDisplayHomeAsUpEnabled(true)it.setDisplayShowHomeEnabled(true)}}}override fun onOptionsItemSelected(item: MenuItem?): Boolean {when (item?.itemId) {//将滑动菜单显示出来android.R.id.home -> {finish()return true}}return super.onOptionsItemSelected(item)}
}
复制代码
ToolbarActivity
继承 BaseActivity, 方便于显示 Toolbar,在项目中挺常用的,所以就封装这个Toolbar基本用法。
- Toolbar title 的显示
- Toolbar 返回键(
android.R.id.home
)的关闭操作。 toolbarTitle
: 可以更改 toolbar 对应的 title
在 Activity 的 xml 引入 Toolbar控件, 并且 id 必须为
toolbar
,否则不会调用initToolbar
初始化方法 !!!
MvpActivity
abstract class MvpActivity<P : BaseContract.Presenter> : ToolbarActivity(), BaseContract.View {lateinit var presenter: Poverride fun initBefore() {presenter = bindPresenter()}abstract fun bindPresenter(): Poverride fun showError(@StringRes msgRes: Int) {showError(getString(msgRes))}override fun showError(msg: String) {toast(msg)hideLoading()}override fun showLoading() {}override fun hideLoading() {}override fun onDestroy() {super.onDestroy()if (::presenter.isInitialized) {presenter.detachView()}}
}
复制代码
MvpActivity 同样是继承ToolbarActivity, 实现了基本 BaseContract.View
, 管理着 Presenter 生命周期
。子类需要实现 bindPresenter()
方法,传递对应的 Presenter。 然后就可以调用 Presenter 进行后续的操作。
- 封装了
Presenter
初始化,销毁 - 复写
showError()
,showLoading()
,hideLoading()
等方法。(简单toast 了)
::presenter.isInitialized
意思是判断 Presenter 是否懒加载初始化, 防止未初始化,抛异常。
后续可能会通过泛型T
, 反射生成Presenter,减少重复操作
Fragment
BaseFragment
、MvpFragment
的实现和 Activity 实现异曲同工,这里就不过多介绍了~
Presenter
abstract class BasePresenter<V : BaseContract.View>(view: V) : BaseContract.Presenter{val view: V?get() = mViewRef.get()// View 接口类型的弱引用private var mViewRef = WeakReference(view)val presenterScope: CoroutineScope by lazy {CoroutineScope(Dispatchers.Main + Job())}fun launchUI(block: suspend CoroutineScope.() -> Unit, error: ((Throwable) -> Unit)? = null) {presenterScope.launch {tryCatch({block()}, {error?.invoke(it) ?: view?.showError(it.toString())})}}override fun detachView() {mViewRef.clear()// 取消掉 presenterScope创建的所有协程和其子协程。presenterScope.cancel()}
}
复制代码
- 绑定
View
的初始化, 销毁, 采用 弱引用方式, 防止内存泄露。 launchUI
封装 协程,切换到 Main线程方法,并进行tryCatch 捕获异常。presenterScope
的销毁,绑定到 对应 UI界面 的onDestory
方法,防止内存泄露。
Model
abstract class BaseModel {suspend fun <R> launchIO(block: suspend CoroutineScope.() -> R) = withContext(Dispatchers.IO) {block()}
}
复制代码
BaseModel 相对简单, 封装了协程切换 IO 线程的操作.
后续可能添加相关 DB 相关操作
Retrofit
class MyRetrofitConfig : BaseRetrofitConfig() {override val baseUrl: Stringget() = API.BASE_URLoverride val readTimeOut: Longget() = //TODOoverride val writeTimeOut: Longget() = //TODOoverride val connectTimeOut: Longget() = //TODOoverride fun initRetrofit(): Retrofit {// 默认实现 BaseRetrofit.init()return Retrofit.Builder().baseUrl(KtArmor.retrofit.baseUrl).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(CoroutineCallAdapterFactory()).client(KtArmor.retrofit.initOkHttpClient()).build()}override fun initOkHttpClient(): OkHttpClient {// 可以传递 Interceptor 进行网络请求拦截return BaseOkHttpClient.init(TokenInterceptor.create())}
}
复制代码
Retrofit 相关网络操作, 可以继承BaseRetrofitConfig
类, 在这里可以配置自己的参数进行扩展, 相关参数如下:
baseUrl
: 网络请求的 baseUrl
initRetrofit
: 为初始化 Retrofit方法,可以返回自定Retrofit
。- 默认实现
BaseRetrofit.init()
- 默认实现
initOkHttpClient
初始化 OkHttp的方法,可以返回自定Okhttp
。- 默认实现
BaseOkHttpClient.init()
init()
方法可以传入对应的Interceptor
, 进行拦截网络操作.readTimeOut
,writeTimeOut
,connectTimeOut
可以复写网络连接超时属性
- 默认实现
SharedPreferences
KtArmor-MVP 通过代理方式,封装了 SharedPreferences基本操作.
- 通过定义一个变量,并通过
by Preference
代理 - 传递 Sp的
key
和对应的defaultValue
值
例如
var account by Preference(Key.ACCOUNT, "")
复制代码
定义了一个 account 变量,传递对应Sp 存储的key,和默认值 “” (空串, 说明account 是 String
类型)
然后直接当正常变量使用, 如下直接赋值 就可以修改 Sp 中key
为 Key.ACCOUNT
的值了。代码如下
account = "123"
复制代码
tryCatch
// 传统的 tryCatchtry{// TODO}catch (e: Exception){// TODO }// KtArmor-MVP 扩展tryCatch({// TODO})// KtArmor-MVP 扩展tryCatch({// TODO}, {// TODO})
复制代码
扩展函数
Toast
扩展, 不重复showToast,多次点击会替换支持
:Context,Activity, Fragment 扩展扩展参数
:string
(或 @StringRes ),duration
- 全局 Toast, 通过 Toasts.show(xx)
sp
,dp
相互转化支持
:Float to Float, Int to Int
Log
支持
:string.showLog()示例
:"我是Log".showLog() 复制代码
R.color.xxx -> Color Int
,R.drawable.xxx -> Drawable
扩展支持
:Context,View 下扩展示例
:val defaultColor: Int = context.getColorRef(R.color.xxx) val defaultDrawable: Drawable? = context.getDrawableRef(R.drawable.xxx) 复制代码
startActivity
参照 anko 的 startActivity (fuzhi)支持
:Context, Fragment 下扩展示例
:startActivity<XXXActivity>(key to value) 复制代码
View
相关扩展TextView
扩展示例
:// 直接获取 TextView 的 text 值 mTvAccount.str() 复制代码
- View 显示隐藏扩展
示例
:mIvImage.visible() 复制代码
- 显示,关闭软键盘扩展
支持
:View, Activity示例
:activity.hideKeyboard() 复制代码
- ...
最后
以上是KtArmor-MVP 的全部内容,后续框架有更新,也会更新相关文档。
还是那句话,KtArmor-MVP 封装了基本 MVP结构的框架,是一款小而美的框架,麻雀虽小五章俱全。封装了基础的功能,小的项目,或者测试项目可以直接拿来用,省时省力。希望大家喜欢~
最后,若有不妥,望小伙伴们指出。
Kotlin的魔能机甲——KtArmor(一)
Kotlin的魔能机甲——KtArmor插件篇(二)
KtArmor-MVP 源码传送门
感谢阅读,下次再见
转载于:https://juejin.im/post/5d4a872e51882575595c40f1
Kotlin的魔能机甲——KtArmor(三)相关推荐
- Kotlin的魔能机甲——KtArmor网络调用封装(四)
前言 继上次分享KtArmor的基础使用方法, 在网络请求逻辑上,在调用上,总感觉不够优雅直观,嵌套过深的问题,这样使得代码看起来臃肿,不美观.所以在这篇中,分享一下我在网络请求调用方面的 封装之路. ...
- Kotlin的魔能机甲——KtArmor(一)
前言 学习了Kotlin有一段时间了, 每次写项目/Demo的时候, 总是用到网络请求.MVP.MVVM.常用工具类.通用自定义View, 索性把这些整合到一起, 搭成一个Android的脚手架--K ...
- 阿俊带你用Kotlin刷算法(三)
本系列通过Java和Kotlin这两种语言来解决力扣上面的算法题,由于本人算法菜鸟一枚,可能部分题目并不是最优题解,希望能和各位大神共同讨论~ 阿俊带你用Kotlin刷算法(一) 阿俊带你用Kotli ...
- Kotlin修炼指南(三)——奇技淫巧
Kotlin作为Android开发的首选语言,为开发者提供了大量的语法糖和技巧,让开发者可以专注于需求开发,而将语言所带来的影响减少到最少.Java和Kotlin最大的区别,实际上在于Kotlin的函 ...
- Kotlin学习笔记 第三章 函数 高阶函数 lambda表达式 内联函数
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- Kotlin学习日志(三)控制语句
一.条件分支 1.1 简单分支 最简单的分支莫过于if-else了吧,Java中相信都用过,那么在Kotlin中又是怎么用的呢?其实也比较类似,来看看吧! 布局文件中: <TextViewand ...
- Kotlin骚气写法 三
文章目录 ViewGroup获取ChildView集合 inline noinline crossinline比较 Kotlin 简化 Parcelable orEmpty() kotlin 代理 关 ...
- Kotlin学习笔记(三):Kotlin中的函数
一.函数的特性语法 函数的几种声明形式 //普通声明形式fun sayHello(str: String){print(str)}//允许参数有默认值,可用于方法重载fun printName(str ...
- 为数不多的人知道的 Kotlin 技巧及解析(三)
本文没有什么奇淫技巧,都是一些在实际开发中常用的技巧 Google 引入 Kotlin 的目的就是为了让 Android 开发更加方便,自从官宣 Kotlin 成为了 Android 开发的首选语言之 ...
最新文章
- 机器学习与深度学习常见面试问题与答案
- 利用cheat engine以及VC编写游戏修改器
- 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为参数,泛型函数
- Django中object.all
- C++ opengl 使视野转头移动(站桩看世界)
- python分解word文档为多个_用python批量处理word文档
- 虎牙、斗鱼正式达成合并协议;​中国广电正式成立,或催生5G发展新格局;Linux 5.9 释出|极客头条
- Oracle数据库中scott用户不存在的解决方法
- 怎么在堆叠柱状图中体现百分比_微生物门类堆叠柱状图一文解决
- Ubuntu安装文泉驿-微米黑字体
- easyui学习笔记5—panel加载其他的页面
- EXCEL常用技巧总结
- 弹跳机器人 桌游_《碰撞机器人 Ricochet Robots 》介绍
- MySQL limit后面加变量
- 【学习笔记之Openlayers3】要素保存篇(第四篇)
- chap0x10 实战fail2ban防止Basic认证暴力破解和SSH口令爆破
- Outlook创建不了Skype会议的解决方案
- 【JZOJ 100029】【NOIP2017提高A组模拟7.8】陪审团 (贪心+排序)
- 联想hx系列服务器,联想超融合HX系列产品介绍.pptx
- 清华开源virtual—box5.1下载
热门文章
- pppoe linux 配置文件,arm-linux配置pppoe
- h5支付 jsapi支付 扫码支付(场景二)
- 全网最全AD16——PCB布局
- 微信小程序+nginx+php+mysql实现数据库管理【第三期】php代码公布
- wamp3.0.6配置https + Nginx转发 + 满足微信小程序的接口调用域名
- 深圳外籍国际学校ib成绩如何?
- Springboot JAR包获取外置配置文件(打包分离出配置文件)
- Photoshop 如何玩转渐变映射?
- 三只小猪的思路解析及其C语言代码
- HTML使svg整体自适应网页变化、以元素颜色填充、隐藏显示