如何让WearOS中HorizontalPager的当前选中页面获得焦点?
解决WearOS HorizontalPager页面切换后ScalingLazyColumn无法获取焦点的问题
核心思路是监听Pager页面切换事件,主动将焦点分配给当前选中页面的ScalingLazyColumn,具体实现步骤如下:
关键修改点
- 为每个页面创建独立的
FocusRequester:不能共用同一个请求器,否则焦点无法精准定位到当前页的列表组件 - 监听Pager状态变化,触发焦点请求:当页面切换完成后,主动调用当前页列表的焦点请求方法
- 确保焦点请求在组件初始化完成后执行:利用
LaunchedEffect保证请求时机的合理性
修改后的完整代码示例
HorizontalPager(state = pagerState) { pageIndex -> // 为每个页面创建专属的FocusRequester,随页面索引变化重新创建 val focusRequester = remember(pageIndex) { FocusRequester() } val listState = rememberScalingLazyListState() val coroutineScope = rememberCoroutineScope() ScalingLazyColumn( state = listState, modifier = modifier .onRotaryScrollEvent { coroutineScope.launch { listState.scrollBy(it.verticalScrollPixels) listState.animateScrollBy(0f) } true } .focusRequester(focusRequester) .focusable() ) { // 你的列表项内容 items(15) { itemIndex -> Card( modifier = modifier.fillMaxWidth().padding(4.dp), onClick = {} ) { Text( text = "页面 $pageIndex · 项 $itemIndex", modifier = modifier.padding(16.dp) ) } } } // 监听当前页面变化,为选中页面的列表请求焦点 LaunchedEffect(pagerState.currentPage) { if (pagerState.currentPage == pageIndex) { // 可选:若页面有复杂布局,可添加短暂延迟确保组件渲染完成 // delay(100) focusRequester.requestFocus() } } }
代码说明
- 独立FocusRequester:通过
remember(pageIndex)为每个页面索引绑定唯一的焦点请求器,避免不同页面复用请求器导致焦点混乱。 - 页面切换监听:
LaunchedEffect(pagerState.currentPage)会在Pager当前页面变化时触发,判断当前组合的页面是否为选中页,若是则调用requestFocus()让列表获得焦点。 - 焦点前提保障:确保
ScalingLazyColumn添加了.focusable()修饰符,这是组件能够获取焦点的必要条件。
内容的提问来源于stack exchange,提问作者FloTec09
相关产品推荐
相关产品推荐

