一文快速了解 Android KTX

Android 提供了各种 Kotlin 类和方法等来简化开发的代码。常见的 Android KTX 模块有core-ktxfragmentlifecycle 等等,下面介绍最常用的一些扩展方法。

core-ktx 模块

Core KTX 模块为属于 Android 框架的通用库提供扩展程序。要使用它,先需要引入下面的依赖:

gradle 复制代码
implementation("androidx.core:core-ktx:1.10.1")

Core KTX 模块内也包含了很多类和方法,主要分为:animationcontentdatabasegraphicsnetostexttransitionutilview 等等。下面就介绍我们开发中常用的几个扩展方法。如果你想了解所有的 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 协程与架构组件一起使用

参考

相关推荐
帅得不敢出门10 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
我又来搬代码了11 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任13 小时前
Mac和安卓手机互传文件(ADB)
android·macos
芦半山13 小时前
Android“引用们”的底层原理
android·java
迃-幵14 小时前
力扣:225 用队列实现栈
android·javascript·leetcode
大风起兮云飞扬丶14 小时前
Android——从相机/相册获取图片
android
Rverdoser14 小时前
Android Studio 多工程公用module引用
android·ide·android studio
aaajj14 小时前
[Android]从FLAG_SECURE禁止截屏看surface
android
@OuYang14 小时前
android10 蓝牙(二)配对源码解析
android
Liknana15 小时前
Android 网易游戏面经
android·面试