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的人真是个天才。。。

相关推荐
洞见前行8 分钟前
Android第二代加固技术原理详解(附源码)
android
风清云淡_A14 分钟前
【JetCompose】入门教程实战基础案例01之显隐动画
android
2501_9160074731 分钟前
iPhone APP 性能测试怎么做,除了Instruments还有什么工具?
android·ios·小程序·https·uni-app·iphone·webview
2501_9151063236 分钟前
Windows 环境下有哪些可用的 iOS 上架工具, iOS 上架工具的使用方式
android·ios·小程序·https·uni-app·iphone·webview
冬奇Lab2 小时前
稳定性性能系列之六——Java异常与JE分析实战
android·性能优化·debug
爱装代码的小瓶子2 小时前
【c++进阶】c++11的魔法:从模板到可变模板.
android·开发语言·c++
lxysbly3 小时前
安卓MD模拟器下载指南2026
android
冬奇Lab4 小时前
Android反模式警示录:System.exit(0)如何制造546ms黑屏
android·性能优化·debug
少年执笔4 小时前
android新版TTS无法进行语音播报
android·java
2501_946244784 小时前
Flutter & OpenHarmony OA系统底部导航栏组件开发指南
android·javascript·flutter