我有一个TvLazyColumn里面包含着TvLazyRows。当我浏览到所有列表的末尾(位置[20,20])并导航到下一个屏幕然后返回时,焦点被恢复到第一个可见位置[15,1],而不是之前的位置[20,20]。 如何将焦点恢复到特定的位置?
class MainActivity : ComponentActivity() {
private val rowItems = (0..20).toList()
private val rows = (0..20).toList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
MyAppNavHost(navController = navController)
}
}
@Composable
fun List(navController: NavController) {
val fr = remember {
FocusRequester()
}
TvLazyColumn( modifier = Modifier
.focusRequester(fr)
.fillMaxSize()
,
verticalArrangement = Arrangement.spacedBy(16.dp),
pivotOffsets = PivotOffsets(parentFraction = 0.05f),
) {
items(rows.size) { rowPos ->
Column() {
Text(text = "Row $rowPos")
TvLazyRow(
modifier = Modifier
.height(70.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
pivotOffsets = PivotOffsets(parentFraction = 0.0f),
) {
items(rowItems.size) { itemPos ->
var color by remember {
mutableStateOf(Color.Green)
}
Box(
Modifier
.width(100.dp)
.height(50.dp)
.onFocusChanged {
color = if (it.hasFocus) {
Color.Red
} else {
Color.Green
}
}
.background(color)
.clickable {
navController.navigate("details")
}
) {
Text(text = "Item ${itemPos.toString()}", Modifier.align(Alignment.Center))
}
}
}
}
}
}
LaunchedEffect(true) {
fr.requestFocus()
}
}
@Composable
fun MyAppNavHost(
navController: NavHostController = rememberNavController(),
startDestination: String = "list"
) {
NavHost(
navController = navController,
startDestination = startDestination
) {
composable("details") {
Details()
}
composable("list") { List(navController) }
}
}
@Composable
fun Details() {
Box(
Modifier
.background(Color.Blue)
.fillMaxSize()) {
Text("Second Screen", Modifier.align(Alignment.Center), fontSize = 48.sp)
}
}
}
版本
dependencies {
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.activity:activity-compose:1.7.1'
implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.material3:material3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
// Compose for TV dependencies
def tvCompose = '1.0.0-alpha06'
implementation "androidx.tv:tv-foundation:$tvCompose"
implementation "androidx.tv:tv-material:$tvCompose"
def nav_version = "2.5.3"
implementation "androidx.navigation:navigation-compose:$nav_version"
}
我尝试将FocusRequestor传递给列表中的每个可聚焦元素。在这种情况下,我能够恢复焦点。但是对于列表中大量的元素,它会开始崩溃并出现OutOfMemoryError。因此,我需要另一种解决方案。
LaunchedEffect(true)
不能保证在运行之前项目就会在视图中。更好的方法是使用onGloballyPositionChanged
或onPlaced
修饰符来验证项目是否在视图中,然后请求对其进行焦点操作。参考票号:gBug - 276738340 - vighnesh153LaunchedEffect(true)
不能保证在运行之前项目会在视图中。更好的方法是使用onGloballyPositionChanged
或onPlaced
修饰符来验证项目是否在视图中,然后请求对其进行焦点设置。参考工单:gBug - 276738340 - undefined