Jetpack Compose Pager中如何实现页面切换后TextField自动获焦?
解决Pager页面切换动画结束后TextField自动获取焦点的问题
要解决动画未结束TextField就提前获取焦点的问题,核心是等待页面切换动画完全结束后再触发焦点请求。因为pagerState.currentPage在动画开始时就会更新,直接通过它判断会导致焦点提前触发,我们需要结合pagerState.isScrollInProgress状态来判断滚动是否完成。
修改后的完整代码示例
主Pager页面
@Composable fun PagerScreen() { val pagerState = rememberPagerState() val pageList = listOf<@Composable () -> Unit>( { Page1(pagerState) }, { Page2(pagerState) }, { Page3(pagerState) } ) HorizontalPager( state = pagerState, userScrollEnabled = false, count = pageList.size ) { index -> pageList[index]() } }
单个页面组件(以Page1为例,其他页面同理修改)
@Composable fun Page1(pagerState: PagerState) { val scope = rememberCoroutineScope() val focusRequester = remember { FocusRequester() } val nextPage = pagerState.currentPage + 1 var text by remember { mutableStateOf(TextFieldValue("")) } // 监听页面状态,滚动停止且当前页为该页面时请求焦点 LaunchedEffect(pagerState.currentPage, pagerState.isScrollInProgress) { // Page1对应索引0,Page2对应1,以此类推 if (!pagerState.isScrollInProgress && pagerState.currentPage == 0) { focusRequester.requestFocus() } } Column { TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) ) Button( onClick = { scope.launch { pagerState.animateScrollToPage(nextPage) } } ) { Text(text = "下一页") } } }
关键说明
- FocusRequester:为每个页面的TextField绑定
FocusRequester,用于主动触发焦点请求。 - LaunchedEffect监听状态:通过
LaunchedEffect监听pagerState.currentPage和pagerState.isScrollInProgress的变化:isScrollInProgress为false时,说明页面切换动画已经完成。- 同时判断当前页是否为该页面的索引,避免其他页面切换时误触发焦点。
- 其他页面适配:只需要将
LaunchedEffect中的索引值改成对应页面的序号(比如Page2改成1,Page3改成2)即可。
内容的提问来源于stack exchange,提问作者Mustafa Tatarhan
相关产品推荐
相关产品推荐

