Android 提供了各种 Kotlin 类和方法等来简化开发的代码。常见的 Android KTX 模块有core-ktx
、fragment
、lifecycle
等等,下面介绍最常用的一些扩展方法。
core-ktx 模块
Core KTX 模块为属于 Android 框架的通用库提供扩展程序。要使用它,先需要引入下面的依赖:
gradle
implementation("androidx.core:core-ktx:1.10.1")
Core KTX 模块内也包含了很多类和方法,主要分为:animation、 content、database、graphics、net、os、 text、transition、 util、view 等等。下面就介绍我们开发中常用的几个扩展方法。如果你想了解所有的 Core KTX 模块的扩展方法,可以看core-ktx的文档
- View
View 是我们在Android中最常用的控件了。在 Core KTX 模块中就提供了很多对应的扩展方法。常用的扩展方法如下所示:
kotlin
// view 转 bitmap
view.drawToBitmap()
// 监听View的 OnAttach 事件,内部调用 addOnAttachStateChangeListener
// 方法,调用一次后就会移除监听
view.doOnAttach { }
// 监听View的 OnDetach 事件,只调用一次
view.doOnDetach { }
// 监听View的Layout事件,只调用一次
view.doOnLayout { }
// 同 doOnLayout 的作用。区别是如果View之前已经Layout了,doOnLayout会立即调用
// 而 doOnNextLayout 会等下一次Layout
view.doOnNextLayout { }
// 在 Draw 方法之前执行对应代码块,只执行一次
view.doOnPreDraw { }
// 对于TextView,core-ktx还提供了对应监听text变化的扩展方法
textView.doBeforeTextChanged { text, start, count, after -> }
textView.doOnTextChanged { text, start, before, count -> }
textView.doAfterTextChanged { }
textView.addTextChangedListener { }
// 更新View的可见性
view.isVisible = false
view.isInvisible = false
view.isGone = false
// 更新间距
view.updatePadding(left = 0, top = 0, right = 0, bottom = 0)
view.updateLayoutParams<LinearLayout.LayoutParams> {
width = 0
height = 0
gravity = Gravity.CENTER_HORIZONTAL
}
- graphics
在 graphics 模块中最常用的是 Bitmap、Drawable 以及 Canvas。它们的常用扩展方法如下所示:
kotlin
// Bitmap 与 Drawable 之间的相互转换
bitmap.toDrawable(resources)
drawable.toBitmap()
// 提供Canvas来绘制Bitmap的扩展方法
bitmap.applyCanvas {
drawColor(resources.getColor(R.color.purple_200))
}
// 使用Canvas绘制是,无需再调用 save 和 restoreToCount,内部
// 会帮你实现
canvas.withSave { }
// 和 withSave 类似,不同的是它先会执行了旋转操作
canvas.withRotation(degrees = 90f) { }
// 和 withSave 类似,不同的是它先会执行了裁剪操作
canvas.withClip(0, 0, 0, 0) { }
// 和 withSave 类似,不同的是它先会设置Matrix
canvas.withMatrix { }
// 和 withSave 类似,不同的是它先会执行了缩放操作
canvas.withScale { }
// 和 withSave 类似,不同的是它先会执行了偏转操作
canvas.withSkew { }
// 和 withSave 类似,不同的是它先会执行了位移作
canvas.withTranslation { }
- 动画
Android的动画本身也有很多Listener,对此Android的core-ktx也做了很多的扩展,代码如下所示:
kotlin
animator.doOnStart { }
animator.doOnPause { }
animator.doOnResume { }
animator.doOnEnd { }
animator.doOnRepeat { }
animator.doOnCancel { }
animator.addListener { }
animator.addPauseListener { }
- net
net 模块比较简单,只提供了 Uri、file、String 之间的转化的扩展方法。代码如下:
kotlin
String.toUri() // 字符串转化为Uri
file.toUri() // 文件转化为 Uri
uri.toFile() // Uri转化为文件
- OS
os模块下有很多的扩展方法,但就 bundleOf
这一个扩展方法我觉得很有用。我们可以使用它往 Bundle 添加各种的value对象。
kotlin
bundleOf(
"key1" to 123,
"key2" to "123",
"key3" to true,
"key4" to 'k',
"key5" to emptyList<String>(),
"key6" to Bundle(),
)
- text
kotlin
//是否只包含数字,相当于 TextUtils.isDigitsOnly
String.isDigitsOnly()
//获取字符串去除头尾空格之后的长度,相当于 TextUtils.getTrimmedLength
String.trimmedLength()
// 便携地创建富文本
val spannedString = buildSpannedString {
bold {} // 加粗
color(color) {} // 颜色
underline {} // 下划线
backgroundColor(color) {} //背景颜色
italic {} // 斜体
scale(1.5F) {} // 缩放
strikeThrough {} //删除线
subscript{} //下标
superscript{} //上标
}
Fragment ktx
要使用Fragment ktx,首先要引入依赖。
kotlin
dependencies {
implementation("androidx.fragment:fragment-ktx:1.6.2")
}
Fragment 常用的扩展方法如下
kotlin
// 通过 commit 方法来简化 commit 操作
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
// 通过 commitNow 方法来简化 commitNow 操作
fragmentManager().commitNow {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
// 通过kotlin委托的方式,获取当前Fragment下的 viewModel
val viewModel by viewModels<MyViewModel>()
// 通过kotlin委托的方式,获取activity下的 viewModel,同一个activity下的不同Fragment
// 可以共享同一个viewModel
val viewModel by activityViewModels<MyViewModel>()
如果还不理解kotlin的委托,可以看一文理解 Kotlin 的委托
Lifecycle KTX
Lifecycle KTX 是 Google 提供的一种在指定的生命周期更方便地执行代码的方式。通过它的 API,我们就可以通过简单的方式来实现复杂的操作。其中最重要的是 lifecycleScope
,它是 Lifecycle KTX 提供的监听 Lifecycle 的协程 Scope。通过它启动的协程会在生命周期进入 DESTROY 时取消通过它启动的协程任务。
上图是launchWhenStarted 和 repeatOnLifecycle 比较优势图,图片来源launchWhenX 给我弃用了,这可咋整。可以看到:
- launchWhenStarted 可以指定在
onStart
的生命周期执行协程协程代码,并在生命周期状态低于指定状态时挂起就会挂起协程。类似的方法还有 launchWhenCreated、launchWhenResumed。 - repeatOnLifecycle(Lifecycle.State.STARTED) 则会在指定
onStart
的生命周期执行协程协程代码,生命周期状态低于指定状态时就会取消协程的执行。然后在onStart
时重新开始执行。 - withStarted 与 launchWhenStarted 类似,区别是 withStarted 需要在
lifecycleScope.launch
中使用,其执行代码块不能使用挂起函数。
kotlin
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
//可以使用挂起函数
delay(1000)
}
lifecycle.withStarted {
//不可以使用挂起函数
}
}
lifecycleScope.launchWhenStarted {
//可以使用挂起函数
delay(1000)
}
ViewModel ktx
与 lifecycleScope
类似,ViewModel 也有一个 viewModelScope
,它们的作用类似。viewModelScope
启动的协程会在ViewModel清除(onCleared)后自动取消。如果你想了解更多关于 ViewModel 的使用,可以看 深入理解Jetpack------ViewModel
LiveData ktx
首先添加依赖
kotlin
dependencies {
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.1")
}
LiveData ktx 主要提供了 liveData
来与协程一起使用,代码示例如下:
kotlin
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
如需详细了解如何将协程与 LiveData
一起使用,可以看将 Kotlin 协程与架构组件一起使用。