You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中如何检测屏幕重组完成并设置Text无障碍焦点?

解决Compose中组件显示后延迟请求焦点的问题

你的问题核心在于Compose的重组是异步过程:当isVisible从false切换为true时,代码里直接调用focusRequester.requestFocus()的时机太早,此时Text组件还没完成布局和挂载,FocusRequester还未和Text绑定,导致焦点请求失败。

下面提供两种可靠的解决方案:

方案一:使用LaunchedEffect(推荐)

利用LaunchedEffect的生命周期特性,它会在重组完成且传入的key值变化时启动协程,此时组件已经完成渲染和绑定,焦点请求会生效。

var isVisible by remember { mutableStateOf(false) }
val focusRequester = remember { FocusRequester() }

if (isVisible) {
    Text(
        text = "Text",
        modifier = Modifier
            .focusRequester(focusRequester)
            .focusable()
    )
    // 当isVisible变为true时,在重组完成后执行焦点请求
    LaunchedEffect(isVisible) {
        focusRequester.requestFocus()
    }
}

Button(onClick = { isVisible = true }) {
    Text(text = "Make text appear and focused")
}

LaunchedEffect以isVisible作为key,只有当isVisible的值发生变化时才会触发内部逻辑,完美匹配"组件显示后请求焦点"的需求,且代码简洁。

方案二:使用onGloballyPositioned回调

通过onGloballyPositioned modifier监听组件的布局完成事件,当组件完成绘制布局后再请求焦点,确保组件已完全挂载。

var isVisible by remember { mutableStateOf(false) }
val focusRequester = remember { FocusRequester() }
// 标记是否已请求过焦点,避免重复触发
val hasRequestedFocus = remember { mutableStateOf(false) }

if (isVisible) {
    Text(
        text = "Text",
        modifier = Modifier
            .focusRequester(focusRequester)
            .focusable()
            .onGloballyPositioned {
                if (!hasRequestedFocus.value) {
                    focusRequester.requestFocus()
                    hasRequestedFocus.value = true
                }
            }
    )
}

Button(onClick = { 
    isVisible = true 
    // 每次点击按钮显示组件时,重置焦点请求标记
    hasRequestedFocus.value = false
}) {
    Text(text = "Make text appear and focused")
}

这种方式适合需要精确监听布局完成时机的场景,但需要额外维护hasRequestedFocus状态来避免窗口 resize 等场景下重复请求焦点。

内容的提问来源于stack exchange,提问作者user22376410

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:05:55