AndroidTV FocusRestorer移除焦点节点后无法回退焦点的问题咨询
临时解决方案:Android TV LazyRow焦点丢失回退异常问题
针对你遇到的LazyRow移除获焦节点后,默认focusRestorer未触发指定回退焦点的问题,以下是几个可落地的临时处理方案:
方案1:手动追踪焦点位置并在数据更新后重定向
- 提前记录当前获焦卡片的行索引和列索引(可存在ViewModel或
remember状态中) - 在LazyRow数据更新完成后,检查原焦点位置是否还在新数据范围内:
- 若存在,通过对应位置的
FocusRequester主动请求焦点 - 若不存在,直接请求预设的回退焦点(比如该行首个可见项)
- 若存在,通过对应位置的
- 核心代码示例:
// 保存当前焦点的行、列索引 var focusedRow by remember { mutableStateOf(0) } var focusedCol by remember { mutableStateOf(0) } // 卡片项中监听焦点变化 Card( modifier = Modifier .onFocusChanged { if (it.isFocused) { focusedRow = currentRowIdx focusedCol = currentColIdx } } ) { /* 卡片内容 */ } // 数据更新后触发焦点调整 LaunchedEffect(swimlaneData) { val targetSwimlane = swimlaneData.getOrNull(focusedRow) ?: swimlaneData.first() val targetIdx = if (focusedCol < targetSwimlane.size) focusedCol else 0 // 假设focusRequesters是按行存储的FocusRequester列表 focusRequesters[focusedRow][targetIdx].requestFocus() }
方案2:自定义焦点恢复逻辑,替代默认focusRestorer
- 移除LazyRow上默认的
focusRestorer,改用onFocusEvent监听焦点移除事件 - 当检测到焦点因节点被移除而丢失时,主动触发回退焦点请求:
val fallbackRequester = remember { FocusRequester() } LazyRow( modifier = Modifier .onFocusEvent { event -> // 监听焦点因节点被移除而丢失的事件 if (event.type == FocusEventType.Unfocus && event.cause == FocusEventCause.Removal) { fallbackRequester.requestFocus() } } ) { items(swimlaneItems) { item -> val isFirstItem = /* 判断是否为该行首个可见项 */ if (item.isPlaceholder) { Placeholder(modifier = Modifier.focusable()) } else { Card( modifier = Modifier .then(if (isFirstItem) Modifier.focusRequester(fallbackRequester) else Modifier) .focusable() ) { /* 卡片内容 */ } } } }
方案3:复用占位符与真实卡片的FocusRequester
- 为每个列表位置创建固定的
FocusRequester,不管显示占位符还是真实卡片都复用同一个 - 当数据加载完成替换占位符时,焦点会自动保留在原位置的真实卡片上:
// 根据列表大小初始化固定的FocusRequester列表 val requesters = remember(swimlaneItems.size) { List(swimlaneItems.size) { FocusRequester() } } LazyRow { itemsIndexed(swimlaneItems) { idx, item -> if (item.isLoading) { Placeholder( modifier = Modifier .focusRequester(requesters[idx]) .focusable() ) } else { Card( modifier = Modifier .focusRequester(requesters[idx]) .focusable() ) { /* 卡片内容 */ } } } }
内容的提问来源于stack exchange,提问作者Da_Shizzle
相关产品推荐
相关产品推荐

