snapshotFlow的使用

一、一句话核心

snapshotFlow = 把 Compose 的 State 变化,转换成 Kotlin Flow

  • 监听 State/MutableState 的变化
  • 每次 State 更新 → 自动发射新值到 Flow
  • 可以用 Flow 操作符:map / filter / debounce / distinctUntilChanged
  • 常用于:State 防抖、State 转换、State 监听异步化

二、核心作用

Compose 状态变化 → 变成 Flow 流 让你能用响应式编程处理状态:

  • 搜索框防抖
  • 状态过滤
  • 状态合并
  • 状态延迟
  • 状态转换

三、最简单示例

scss 复制代码
// 一个 Compose State
val textState = remember { mutableStateOf("") }

// 把 State 转成 Flow
val flow = snapshotFlow { textState.value }

// 像普通 Flow 一样使用
LaunchedEffect(Unit) {
    flow.collect { text ->
            // 每次 textState 变化,这里都会收到新值
            Log.d("Flow", "新文本:$text")
    }
}

四、完整语法

kotlin

kotlin 复制代码
fun <T> snapshotFlow(block: () -> T): Flow<T>

规则

  1. block 中必须读取 State
  2. State 变化 → Flow 自动发射
  3. 不读取 State → 不会发射
  4. 内部使用 Snapshot 系统(Compose 底层监听机制)

五、最经典使用场景

场景 1:搜索框 防抖(最常用)

kotlin

scss 复制代码
val searchState = remember { mutableStateOf("") }

LaunchedEffect(Unit) {
    snapshotFlow { searchState.value }
        .debounce(500)       // 防抖 500ms
        .filter { it.length > 2 } // 过滤长度>2
        .collect { query ->
            // 执行搜索
            viewModel.search(query)
        }
}

场景 2:监听状态变化

kotlin 复制代码
val countState = remember { mutableStateOf(0) }

LaunchedEffect(Unit) {
    snapshotFlow { countState.value }
        .collect {
        Log.d("Count", "计数:$it")
    }
}

场景 3:多个 State 合并监听

kotlin

scss 复制代码
val a = remember { mutableStateOf(1) }
val b = remember { mutableStateOf(2) }

LaunchedEffect(Unit) {
    snapshotFlow { a.value + b.value } // 任意一个变化都会触发
        .collect { sum ->
            Log.d("Sum", "总和:$sum")
        }
}

场景 4:状态转换

scss 复制代码
val ampState = remember { mutableStateOf(0f) }

LaunchedEffect(Unit) {
    snapshotFlow { ampState.value }
        .map { it.coerceIn(0f, 1f) } // 限制范围
        .collect {
        waveView.setAmplitude(it)
    }
}

六、核心特点(必记)

  1. 自动监听 State
  2. 只在值变化时发射
  3. 主线程安全
  4. 可使用所有 Flow 操作符
  5. Compose 原生支持,无需依赖
  6. 离开重组范围自动停止

七、snapshotFlow 生命周期

  • LaunchedEffect 中使用

  • 当组件 退出组合

    • Flow 自动取消
    • 不会内存泄漏
  • key 变化

    • 重新启动

八、和 rememberUpdatedState 区别

  • rememberUpdatedState:保证拿到最新值
  • snapshotFlow:把值变化变成 ,可防抖 / 过滤 / 延迟
相关推荐
我命由我1234511 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
MiyamuraMiyako14 小时前
Compose:从自动滚动到双锚点 LazyLayout
android·android jetpack
杉氧4 天前
Compose 渲染内核 (3):Slot Table 与 Gap Buffer —— 极速重组的数学艺术
android·架构·android jetpack
alexhilton4 天前
Kotlin DSL深度解析:从Gradle脚本到构建你自己的DSL
android·kotlin·android jetpack
杉氧7 天前
Framework 补完计划 (2):BufferQueue 与 SurfaceFlinger —— 像素的跨进程“接力赛”
android·架构·android jetpack
我命由我123457 天前
Android 开发问题:ClickableSpan 的点击事件没有生效
java·java-ee·android studio·android jetpack·android-studio·android runtime
我命由我123458 天前
Android 构建项目问题:XML 片段出错,com.ctc.wstx.exc.WstxUnexpectedCharException
android·xml·android studio·android jetpack·android-studio·android runtime
杉氧10 天前
跨平台资源管理:一套代码如何搞定 Android、iOS 和 Web 的图片与多语言?
android·架构·android jetpack
杉氧11 天前
兼容与共生:如何在旧项目中优雅地引入 Compose?
android·架构·android jetpack
杉氧11 天前
性能优化实战:如何定位冗余重组并榨干 Compose 的每一帧性能?
android·架构·android jetpack