Android Jetpack Compose TV 通过导航恢复焦点

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

我的示例应用程序有两个屏幕:主屏幕和详细信息屏幕。 在主屏幕上,我有一个包含 100 个元素的 LazyVerticalGrid,而详细信息屏幕只是一个后退按钮。

在主屏幕上滚动,进入详细信息屏幕并返回时,焦点不会恢复到按下的卡片上。

这是我的示例应用程序的完整代码:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()
            NavHost(
                navController = navController,
                startDestination = "Home"
            ) {
                composable("Home") {
                    val list = rememberSaveable { List(100) { "Card $it" } }
                    LazyVerticalGrid(
                        modifier = Modifier
                            .fillMaxSize(),
                        columns = GridCells.Adaptive(minSize = 70.dp),
                        contentPadding = PaddingValues(horizontal = 40.dp),
                        horizontalArrangement = Arrangement.spacedBy(20.dp),
                        verticalArrangement = Arrangement.spacedBy(20.dp)
                    ) {
                        itemsIndexed(
                            items = list,
                            key = { index, _ -> index }
                        ) { _, item ->
                            var isFocused by remember { mutableStateOf(false) }
                            Box(
                                modifier = Modifier
                                    .onFocusChanged { isFocused = it.hasFocus }
                                    .size(height = 70.dp, width = 70.dp)
                                    .background(Color.Red)
                                    .border(width = 2.dp, color = if (isFocused) Color.White else Color.Transparent)
                                    .clickable { navController.navigate("Details") }
                                    .focusable(),
                                contentAlignment = Alignment.Center
                            ) {
                                Text(text = item)
                            }
                        }
                    }
                }
                composable("Details") {
                    Box(
                        modifier = Modifier.fillMaxSize(),
                        contentAlignment = Alignment.Center
                    ) {
                        Button(
                            onClick = { navController.popBackStack() }
                        ) {
                            Text(text = "Go back")
                        }
                    }
                }
            }
        }
    }
}

有没有简单的方法来实现焦点恢复(无需为所有卡设置焦点恢复器)?

android kotlin android-jetpack-compose focus android-tv
1个回答
1
投票

问题是您的代码在导航过程中不保存焦点位置,请尝试使用 RememberSaveable 进行此修复。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()
            NavHost(
                navController = navController,
                startDestination = "Home"
            ) {
                composable("Home") {
                    val list = rememberSaveable { List(100) { "Card $it" } }
                    LazyVerticalGrid(
                        modifier = Modifier
                            .fillMaxSize(),
                        columns = GridCells.Adaptive(minSize = 70.dp),
                        contentPadding = PaddingValues(horizontal = 40.dp),
                        horizontalArrangement = Arrangement.spacedBy(20.dp),
                        verticalArrangement = Arrangement.spacedBy(20.dp)
                    ) {
                        itemsIndexed(
                            items = list,
                            key = { index, _ -> index }
                        ) { _, item ->
                            var isFocused by rememberSaveable { mutableStateOf(false) }
                            Box(
                                modifier = Modifier
                                    .onFocusChanged { isFocused = it.hasFocus }
                                    .size(height = 70.dp, width = 70.dp)
                                    .background(Color.Red)
                                    .border(width = 2.dp, color = if (isFocused) Color.White else Color.Transparent)
                                    .clickable { navController.navigate("Details") }
                                    .focusable(),
                                contentAlignment = Alignment.Center
                            ) {
                                Text(text = item)
                            }
                        }
                    }
                }
                composable("Details") {
                    Box(
                        modifier = Modifier.fillMaxSize(),
                        contentAlignment = Alignment.Center
                    ) {
                        Button(
                            onClick = { navController.popBackStack() }
                        ) {
                            Text(text = "Go back")
                        }
                    }
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.