You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose聊天应用:软键盘覆盖输入栏及对话无故上移问题

解决方案

1. 配置Activity软键盘适配规则

在AndroidManifest.xml中给目标Activity添加软键盘行为配置,让系统自动调整布局以适配软键盘:

<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="adjustResize">
    <!-- 其他原有配置 -->
</activity>

2. 调整Compose布局,修复输入栏覆盖与不必要滚动问题

修改主布局代码

class MainActivity : ComponentActivity() {

    private val viewModel: MainViewModel by viewModels { ViewModelFactory() }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    val conversationState = viewModel.convo.observeAsState().value ?: emptyList()
                    Column(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(8.dp)
                    ) {
                        // 对话列表:仅内容超出时滚动,填充剩余空间
                        Conversation(
                            modifier = Modifier
                                .weight(1f)
                                .verticalScroll(rememberScrollState()),
                            messages = conversationState
                        )
                        Spacer(modifier = Modifier.height(8.dp))
                        // 输入栏:添加软键盘适配内边距,确保不被覆盖
                        UserInput(
                            modifier = Modifier.imePadding(),
                            onSend = { inputStr ->
                                viewModel.onSubmit(inputStr)
                            }
                        )
                    }
                }
            }
        }
    }
}

更新UserInput组件

@Composable
fun UserInput(
    modifier: Modifier = Modifier,
    onSend: (String)->Unit
) {
    var currentMessage by rememberSaveable { mutableStateOf("") }
    Row(
        modifier = modifier
            .fillMaxWidth()
            .padding(8.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        BasicTextField(
            value = currentMessage,
            onValueChange = { newMessage -> currentMessage = newMessage },
            textStyle = TextStyle(color = Color.Black),
            modifier = Modifier
                .weight(1f)
                .padding(8.dp)
                .background(MaterialTheme.colorScheme.surface, RoundedCornerShape(24.dp))
                .padding(horizontal = 16.dp, vertical = 12.dp)
        )
        Button(onClick = {
            if (currentMessage.isNotBlank()) {
                onSend(currentMessage)
                currentMessage = ""
            }
        }) {
            Text(text = "Send")
        }
    }
}

3. 可选:优化消息自动滚动(新增消息时自动到底部)

如果需要软键盘弹出或新增消息时自动滚动到最新内容,修改Conversation组件:

@Composable
fun Conversation(modifier: Modifier = Modifier, messages: List<Message>) {
    val scrollState = rememberScrollState()
    Column(modifier = modifier) {
        messages.forEach { message ->
            MessageItem(message = message)
            Spacer(modifier = Modifier.height(8.dp))
        }
        // 消息更新时自动滚动到底部
        LaunchedEffect(messages) {
            scrollState.animateScrollTo(scrollState.maxValue)
        }
    }
}

核心原理说明

  • adjustResize:让系统在软键盘弹出时调整Activity布局高度,这是Compose布局响应软键盘的基础。
  • imePadding():自动给输入栏添加与软键盘高度匹配的底部内边距,避免输入栏被覆盖。
  • verticalScroll(rememberScrollState()):让对话列表仅在内容超出可见区域时才触发滚动,避免无意义的整体上移。

内容的提问来源于stack exchange,提问作者HukeLau_DABA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:02:04