Jetpack Compose中OutlinedTextField切换焦点时被键盘遮挡如何解决
Jetpack Compose 软键盘切换焦点后输入框被遮挡解决方案
问题表现
点击软键盘「下一步」切换焦点到Amount输入框时,屏幕没有自动上移,输入框被软键盘遮挡,具体效果如下:
- 未弹出键盘时的UI效果:

- Name输入框获得焦点时的效果:

- Amount输入框获得焦点时的效果:

解决步骤
1. 修改AndroidManifest.xml配置
找到对应页面的Activity节点,添加软键盘调整属性:
<activity android:name=".你的Activity名称" android:windowSoftInputMode="adjustResize" />
该配置会让系统在软键盘弹出时自动压缩Activity的可用显示区域,触发布局重绘。
注意:
bringIntoViewRequester是Jetpack Compose 1.2.0及以上版本提供的API,低于该版本可以升级Compose版本使用。
2. 改造布局支持滚动+自动对齐聚焦控件
你当前使用的是固定Column,没有滚动能力,需要给Column添加滚动修饰符,同时给每个输入框添加聚焦时自动滚动到可见区域的逻辑。
修改后完整代码
@Composable fun KeyboardSample() { Scaffold( modifier = Modifier .fillMaxSize() .padding(start = 16.dp, end = 16.dp), ) { paddingValues -> // 消费Scaffold返回的默认边距 val name = rememberSaveable { mutableStateOf("") } val updateName = { _name: String -> name.value = _name } val amount = rememberSaveable { mutableStateOf("") } val updateAmount = { _amount: String -> amount.value = _amount } TextFieldsToExperiment( name = name.value, updateName = updateName, amount = amount.value, updateAmount = updateAmount, modifier = Modifier .padding(paddingValues) .fillMaxSize() .imePadding() // 自动适配软键盘高度边距 ) } } @Composable fun TextFieldsToExperiment( name: String, updateName: (String) -> Unit, amount: String, updateAmount: (String) -> Unit, modifier: Modifier = Modifier ) { val focusManager = LocalFocusManager.current val coroutineScope = rememberCoroutineScope() Column( modifier = modifier .verticalScroll(rememberScrollState()), // 给Column添加垂直滚动能力 horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Spacer(modifier = Modifier.height(390.dp)) val nameBringRequester = rememberBringIntoViewRequester() OutlinedTextField( value = name, onValueChange = updateName, label = { Text("Name") }, placeholder = { Text(text = "Name") }, singleLine = true, keyboardOptions = KeyboardOptions.Default.copy( capitalization = KeyboardCapitalization.Sentences, autoCorrect = true, keyboardType = KeyboardType.Text, imeAction = ImeAction.Next ), keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Down) }), modifier = Modifier .fillMaxWidth() .padding(top = 6.dp, start = 0.dp, end = 0.dp, bottom = 6.dp) .bringIntoViewRequester(nameBringRequester) .onFocusEvent { state -> if (state.isFocused) { coroutineScope.launch { nameBringRequester.bringIntoView() } } }, ) Text(text = "Hello") Spacer(Modifier.height(8.dp)) val amountBringRequester = rememberBringIntoViewRequester() OutlinedTextField( value = amount, onValueChange = updateAmount, label = { Text("Amount") }, placeholder = { Text(text = "Amount") }, singleLine = true, keyboardOptions = KeyboardOptions.Default.copy( capitalization = KeyboardCapitalization.Sentences, autoCorrect = true, keyboardType = KeyboardType.Text, imeAction = ImeAction.Done ), keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), modifier = Modifier .fillMaxWidth() .padding(top = 6.dp, start = 0.dp, end = 0.dp, bottom = 6.dp) .bringIntoViewRequester(amountBringRequester) .onFocusEvent { state -> if (state.isFocused) { coroutineScope.launch { amountBringRequester.bringIntoView() } } }, ) } }
验证说明
修改完成后重新运行项目,点击下一步切换焦点时,系统会自动滚动布局,保证获得焦点的输入框完整显示在软键盘上方。
内容的提问来源于stack exchange,提问作者Fabiel Casas
相关产品推荐
相关产品推荐

