Compose实现点击防抖,给Modifier添加扩展函数(含扩展函数的原理)

扩展函数的核心原理

  1. 语法层面的 "假象"

    从语法上看,扩展函数似乎是直接 "注入" 到了目标类中,调用时也像调用类的成员函数一样(例如 对象.扩展函数())。但实际上,扩展函数并不会修改目标类的结构,也不会被编译成目标类的成员方法。

  2. 静态解析的工具函数

    编译器会将扩展函数处理为静态工具函数。例如,在 Kotlin 中定义:

    kotlin 复制代码
    fun String.lastChar(): Char {
        return this[this.length - 1]
    }

    编译器会将其转换为类似 Java 的静态方法:

    java 复制代码
    public static Char lastChar(String $this) {
        return $this.charAt($this.length() - 1);
    }

    其中,this 关键字在扩展函数中指向调用该函数的对象实例(即目标类的对象),但本质上是函数的第一个参数。

  3. 编译期绑定,无运行时开销

    扩展函数的调用是编译期确定的,而非运行时动态绑定。编译器会根据调用者的静态类型(声明类型)来匹配对应的扩展函数,而不是根据运行时的实际类型。这意味着:

    • 扩展函数不能覆盖类的成员函数(如果同名,优先调用成员函数)。
    • 无法通过多态实现扩展函数的动态调用。

扩展函数的优势

  1. 避免类膨胀 :无需为扩展功能创建子类或工具类(如 StringUtils),保持代码整洁。
  2. 增强可读性 :调用方式与成员函数一致(对象.函数()),符合直觉。
  3. 兼容第三方类:可以为无法修改源代码的类(如 Java 标准库类、第三方库类)添加功能。

局限性

  1. 无法访问私有 / 受保护成员:扩展函数只能访问目标类的公开成员,因为它本质上是外部函数。
  2. 静态绑定的限制:若子类和父类有同名扩展函数,调用结果由变量的声明类型决定,而非实际类型。
  3. 可能引发命名冲突:多个扩展函数同名时,需要通过显式导入或命名空间区分。

典型应用场景

  • 为基础类型(如字符串、集合)添加便捷操作(如字符串判空、集合过滤)。
  • 为第三方库类补充业务相关功能(如为LocalDateTime添加格式化方法)。
  • 在不破坏原有设计的前提下,逐步扩展类的功能。

Compose实现点击防抖

要求:不破坏Modifier的设计原则的情况下,实现防抖功能

kotlin 复制代码
fun Modifier.debounceClick(
    debounceTime: Long = 2000,
    onClick: () -> Unit
) = this.then( // 使用then()方法连接新的修饰符
   Modifier.composed {
        var lastClickTime by remember { mutableStateOf(0L) }

        Modifier.clickable {
            val currentTime = System.currentTimeMillis()
            if (currentTime - lastClickTime > debounceTime) {
                lastClickTime = currentTime

                onClick()
            }
        }
    }
)

then 是Modifier的方法,作用是用来组合Modifier,我们来看他的源码

kotlin 复制代码
infix fun then(other: Modifier): Modifier =
       //合并
    if (other === Modifier) this else CombinedModifier(this, other)

composed 代码块 返回值是Modifier,composed也是将返回值进行合并,composed的源码

kotlin 复制代码
fun Modifier.composed(
    inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
    factory: @Composable Modifier.() -> Modifier
): Modifier = this.then(ComposedModifier(inspectorInfo, factory))

Modifier.clickable 是 factory的返回值 factory的返回值和ComposedModifier进行合并, 进行合并的结果,再和debounceClick的对象进行合并,这样就对Modifier进行了扩展。实现了点击防抖。 发现发明Modifier的人真是个天才。。。

相关推荐
北有花开1 小时前
Android方法耗时监控插件:基于ASM字节码插桩的性能分析工具
android
whysqwhw1 小时前
React Native应用中实现原生组件与JavaScript组件的复杂交互
android
whysqwhw1 小时前
React Native 中调用 Android 自定义控件
android
往事如烟隔多年2 小时前
一加Ace5无法连接ColorOS助手解决(安卓设备ADB模式无法连接)
android·adb·手机·coloros
00后程序员张2 小时前
iOS软件性能监控实战指南 开发到上线的完整流程解析
android·ios·小程序·https·uni-app·iphone·webview
2401_837088502 小时前
Axios介绍
android·okhttp
智江鹏3 小时前
Android 之 串口通信
android
IH_LZH4 小时前
kotlin小记(1)
android·java·前端·kotlin
凡小烦5 小时前
Retrofit源码解析
android·面试