如何通过 Compose 将焦点移回 Android TV 中恢复的位置?

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

我使用包含多个 LazyRow 的 LazyColumn。

当焦点移动到另一行时,例如从A行移动到B行,我需要恢复A行最后聚焦的位置;当焦点回到A行时,我需要将焦点移动到恢复的位置。我怎样才能做到?

默认情况下,例如焦点位于 B 行第三个位置,当我单击向上按钮将焦点移回 A 行时,焦点也会移动到 A 行第三个位置。

在我的项目中,lazyRow 包含多个 AppCard,例如:

@Composable
fun AppCard(
    app: App,
    modifier: Modifier = Modifier,
    onClick: (App) -> Unit = {}
) {
    Card(
        onClick = { onClick(app) },
        modifier = modifier
            .widthIn(max = 120.dp)
            .aspectRatio(16f / 9f)
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            AsyncImage(
                model = app.appIcon,
                contentDescription = app.appName
            )
        }
    }
}

我尝试在每个AppCard的修改器中初始化一个FocusRequester,但我发现很难知道焦点是否已经离开该行。对于每一行,我需要存储最后的焦点位置。

class CatalogViewModel : ViewModel() {
    private val _categoriesMap = MutableStateFlow<Map<String, List<App>>>(emptyMap())
    val categoriesMap: StateFlow<Map<String, List<App>>> = _categoriesMap
    ...
}


@Composable
fun CatalogBrowser(viewModel: CatalogViewModel) {
    val categoriesMap by viewModel.categoriesMap.collectAsState(emptyMap())
    LazyColumn(
        modifier = modifier,
        verticalArrangement = Arrangement.spacedBy(16.dp),
        contentPadding = PaddingValues(horizontal = 48.dp, vertical = 32.dp)
    ) {
        itemsIndexed(categoriesMap.entries.toList()) { categoryIndex, entry ->
            val (category, appList) = entry
            Column {
                Text(text = category, modifier = Modifier.padding(start = 12.dp))
                Spacer(modifier = Modifier.height(6.dp))

                LazyRow(
                    modifier = Modifier.height(67.5.dp),
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                    contentPadding = PaddingValues(horizontal = 10.dp),
                ) {
                    itemsIndexed(appList) { appIndex, app ->
                        val cardRequester = remember {
                            FocusRequester()
                        }
                        AppCard(
                            modifier = Modifier
                                .focusRequester(cardRequester)
                                .padding(vertical = 6.dp),
                            app = app,
                            onClick = { onCardSelected(app) }
                        )
                    }
                }
            }
        }
    }
}
android-jetpack-compose android-tv android-jetpack-compose-tv
1个回答
0
投票

现在我找到了解决方法。只需简单地将 focusRestorer 添加到修饰符即可修复它,如下所示:

Box(modifier = Modifier.focusRestorer()) {...}

我们还可以将 focusRequester 添加到 focusRestorer,以防使用我们自己的焦点逻辑。

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