当您希望列表中的第一项位于顶部时,如何请求将其聚焦(Jetpack compose)?

问题描述 投票:0回答:1

通过按 2 个按钮之一,我可以在列表的开头添加文本“Apple”或“Orange”,其中该列表将显示在顶部的列中。 每个新文本都会出现在列表顶部。

    val myList = remember { mutableStateListOf<String>() }
    val focus = remember { FocusRequester() }

    Column {
        myList.forEachIndexed { index, word ->
            Text(
                text = word,
                modifier =
                if (index == 0) {
                    Modifier
                        .focusRequester(focus)
                        .focusable()
                } else {
                    Modifier
                }
            )
        }

        if (myList.isNotEmpty()) {
            focus.requestFocus()
        }

        Button(
            onClick = {
                myList.add("Apple")
            },
            modifier = Modifier.padding(top = 8.dp)
        ) {
            Text("Add Apple")
        }

        Button(
            onClick = {
                myList.add("Orange")
            },
            modifier = Modifier.padding(top = 8.dp)
        ) {
            Text("Add Orange")
        }
    }

由于某种原因这不起作用。

出于好奇,我检查了如果我更改它以使最后一项成为焦点会发生什么:

                if (index == myList.size -1) {
                    Modifier
                        .focusRequester(focus)
                        .focusable()
                } else {
                    Modifier
                }

尝试时,辅助功能焦点将转到列表底部的最后一个文本。

那么为什么焦点仅在列表的最后一项而不是第一项(或之前的任何项目)时才起作用?

有办法解决吗?

android kotlin android-jetpack-compose accessibility talkback
1个回答
0
投票

您正在重复使用

FocusRequester
,因此您只需为每个非空列表
requestFocus()
一次。另外,将
requestFocus()
直接放入组合中也不是一个好主意,因为我们无法控制此类请求的执行顺序或频率。所以我建议删除这部分:

if (myList.isNotEmpty()) {
    focus.requestFocus()
}

并添加将执行请求的

LaunchedEffect

if (index == 0) {
    LaunchedEffect(Unit) { focus.requestFocus() }
    Modifier
        .focusRequester(focusRequester)
        .focusable()
} else {
    Modifier
}

您还可以在

delay
中的
requestFocus()
之前添加一个小
LaunchedEffect
,以确保它在添加
focusRequester
修饰符后执行。

© www.soinside.com 2019 - 2024. All rights reserved.