无法聚焦 TextField 以外的任何内容

Unable to Focus Anything other than TextField

我已经查看了网站上的其他帖子。他们建议使用 focusRequestor 修饰符,我已经试过了。

val scope = rememberCoroutineScope()
val focusRequester = remember { FocusRequester() }
Text(
    modifier = Modifier
        .focusable()
        .focusTarget() //Tried Adding/Removing
        .onFocusChanged {
            if (it.hasFocus || it.isFocused) {
                Log.i("Test", "Text Focused")
            }
        } // Tried Adding Visual Elements to delete it as well.
        .focusRequester(focusRequester),
    text = "MARSK"
)

LaunchedEffect(scope) {
    focusRequester.requestFocus()
}

我在这个例子中使用 Text,但实际上我需要在 Canvas 上实现它。这种方法也不适用于 Box。恐怕其他容器也是如此。

作为背景,这是为我的电视制作的,所以我希望通过遥控器方向键上的“确定”按钮可以点击此元素。我的做法是先让它聚焦,然后假设一旦聚焦,它会自动检测按下OK按钮为'click'。如果我的方法有问题,也欢迎反馈改进。

PS:Abhimanyu 的解决方案在移动设备上非常有效。但是,由于我在上面提到了电视,因此考虑的设备就是电视。在电视上,我必须按下一个按钮(奇怪的是,DPAD 上的任何按钮都可以,甚至是 OK 按钮)才能使其聚焦。知道如何解决这个问题吗?

谢谢

问题
onFocusChanged 应添加到正在观察的 focusTargetfocusable 之前。

Source

变化

  1. 删除 focusTarget 并将 onFocusChanged 移到 focusable 之前。
  2. 此外,请注意 focusRequester 必须在 focusable 之前。

这有望适用于所有可组合对象。我已经使用 Text 进行了测试,文档中的示例使用的是 Box.

更多详细信息

  1. focusTarget 更喜欢 focusable

    来自 focusTarget 文档,

Note: This is a low level modifier. Before using this consider using Modifier.focusable(). It uses a focusTarget in its implementation. Modifier.focusable() adds semantics that are needed for accessibility.

  1. 修饰符的顺序很重要
    Layouts in Jetpack Compose Codelab
    检查 Order Matters 部分

order matters when chaining modifiers as they're applied to the composable they modify from earlier to later,

示例代码

@Composable
fun FocusableText() {
    val scope = rememberCoroutineScope()
    val focusRequester = remember { FocusRequester() }
    var color by remember { mutableStateOf(White) }
    LaunchedEffect(scope) {
        focusRequester.requestFocus()
    }
    Text(
        modifier = Modifier
            .background(color)
            .onFocusChanged {
                color = if (it.hasFocus || it.isFocused) {
                    LightGray
                } else {
                    White
                }
            }
            .focusRequester(focusRequester)
            .focusable(),
        text = "Test Text"
    )
}

Text 背景为 LightGray,表示文本已聚焦。