Compose中BoxWithConstraints内局部点击函数无法获取最新maxWidth如何解决
解决方案
你遇到的是Jetpack Compose中闭包捕获旧值的典型场景,这里提供两种常用的修复方案:
方案1:调整pointerInput的依赖key
pointerInput修饰符的入参是触发其重新执行的key,你当前传的是Unit,意味着触摸监听逻辑只会在组件首次挂载时执行一次,内部捕获的constraints值永远是初始值。把maxWidth加入key列表,只要宽度变化,pointerInput就会重新初始化,自动拿到最新的约束值。
修改后代码:
BoxWithConstraints( propagateMinConstraints = true, modifier = Modifier .background(Color.Green) .fillMaxSize() ) { val currentMaxWidth = constraints.maxWidth println("current maxWidth: $currentMaxWidth") fun onTap(position: Offset) { println("onTap maxWidth: $currentMaxWidth") } Box( modifier = Modifier .background(Color.Blue) // 宽度变化时重新执行pointerInput内部逻辑 .pointerInput(currentMaxWidth) { detectTapGestures(onTap = ::onTap) } ) { } }
方案2:用rememberUpdatedState持有最新值
如果不想每次宽度变化都重新初始化触摸监听,可以用Compose提供的rememberUpdatedState包装宽度值,它会在每次重组时自动更新内部持有的值,不需要重新执行pointerInput逻辑就能读取到最新值,性能更优。
修改后代码:
BoxWithConstraints( propagateMinConstraints = true, modifier = Modifier .background(Color.Green) .fillMaxSize() ) { val currentMaxWidth = constraints.maxWidth println("current maxWidth: $currentMaxWidth") // 持有最新的宽度值,重组时自动更新 val latestMaxWidth = rememberUpdatedState(currentMaxWidth) fun onTap(position: Offset) { // 读取state中存储的最新值 println("onTap maxWidth: ${latestMaxWidth.value}") } Box( modifier = Modifier .background(Color.Blue) .pointerInput(Unit) { detectTapGestures(onTap = ::onTap) } ) { } }
两种方案的适用场景:方案1适合触摸逻辑和宽度强相关、宽度变化时需要重置监听的场景;方案2适合仅需要读取最新宽度值、不需要重置监听的场景。
内容的提问来源于stack exchange,提问作者vovahost
相关产品推荐
相关产品推荐

