Jetpack Compose WearOS:RotaryScrollEvents触发时PositionIndicator不显示求助
解决Wear OS旋转滚轮滚动时PositionIndicator不显示的问题
问题根源
手势滚动时系统会自动更新ScrollState的isScrollInProgress状态,PositionIndicator依赖这个状态判断是否显示。但手动调用scrollState.scrollBy()处理旋转滚轮事件时,不会触发该状态更新,导致指示器无法正常显示。
解决方案
在处理RotaryScrollEvent时,手动维护isScrollInProgress状态,模拟手势滚动的显示逻辑:
- 滚动开始时将
isScrollInProgress设为true,触发指示器显示 - 滚动停止后延迟一段时间(与系统默认逻辑一致,比如300ms)将其设为
false,让指示器自动隐藏 - 用任务管理避免连续滚动时状态混乱
修改后的代码示例
@Composable fun WearApp() { val scrollState = rememberScrollState() val coroutineScope = rememberCoroutineScope() val focusRequester = remember { FocusRequester() } // 跟踪滚动超时任务,防止连续滚动时指示器提前隐藏 val scrollTimeoutJob = remember { mutableStateOf<Job?>(null) } Scaffold( positionIndicator = { PositionIndicator( scrollState = scrollState ) } ) { Column ( modifier = Modifier .fillMaxSize() .verticalScroll(scrollState) .onRotaryScrollEvent { event -> coroutineScope.launch { // 取消之前的超时任务 scrollTimeoutJob.value?.cancel() // 标记滚动进行中,显示指示器 scrollState.isScrollInProgress = true // 执行滚动操作 scrollState.scrollBy(event.verticalScrollPixels) // 设置超时任务,停止滚动后隐藏指示器 scrollTimeoutJob.value = launch { delay(300) // 与系统手势滚动的指示器隐藏延迟匹配 scrollState.isScrollInProgress = false } } true } .focusRequester(focusRequester) .focusable(), ) { LaunchedEffect(Unit) { focusRequester.requestFocus() } // 测试用滚动内容 repeat(10) { index -> Output("${index}".repeat(11)) } } } } @Composable fun Output(outStr: String) { Text( modifier = Modifier.fillMaxWidth() .height(50.dp), textAlign = TextAlign.Center, style = TextStyle(fontSize = 25.sp), text = outStr, ) }
补充说明
scrollTimeoutJob用于管理超时任务,确保连续滚动时指示器不会提前消失,只有滚轮停止300ms后才隐藏- 可根据需求调整
delay的时长(系统默认通常在200-300ms区间) - 若改用
ScalingLazyColumn,逻辑类似,只需把ScrollState替换为ScalingLazyListState,并维护其isScrollInProgress状态即可
内容的提问来源于stack exchange,提问作者MikeCalligaro
相关产品推荐
相关产品推荐

