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

Jetpack Compose:键盘弹出时TopAppBar被上推,需固定顶部栏

解决KMM聊天页面键盘弹出时TopAppBar上推的问题

问题根源

你的项目存在嵌套Scaffold结构(主Activity外层Scaffold + 聊天页面内层Scaffold),结合adjustResize的软键盘设置,导致键盘弹出时整个聊天页面布局被整体上推,包括顶部的TopAppBar。同时聊天页面Scaffold的statusBarsPadding()也干扰了布局响应逻辑。

具体解决方案

1. 确认AndroidManifest软键盘模式

保留adjustResize设置,同时确保Activity主题未启用全屏属性(如android:windowFullscreen,否则adjustResize会失效):

android:windowSoftInputMode="adjustResize"

2. 重构聊天页面布局,固定TopAppBar

移除聊天页面的外层Scaffold,改用Column直接包裹固定的TopAppBar和可调整的内容区域,让TopAppBar脱离键盘影响的布局层级:

Column(modifier = Modifier.fillMaxSize()) {
    // 固定在顶部的TopAppBar,单独处理状态栏内边距
    TopAppBar(
        modifier = Modifier
            .fillMaxWidth()
            .requiredHeight(56.dp)
            .background(Color.White)
            .statusBarsPadding(),
        title = {
            // 原有TopAppBar内容保持不变
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .requiredHeight(56.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Image(
                    modifier = Modifier.height(44.dp).width(44.dp).clickable(enabled = true) {
                        component.onEvent(ChatRoomEvents.BackClick)
                    },
                    contentScale = ContentScale.None,
                    painter = painterResource(Res.drawable.back_green),
                    contentDescription = Strings.getString("back")
                )
                // ... 其余TopAppBar子元素省略
            }
        }
    )

    // 可响应键盘调整的内容区域
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        LazyColumn(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
                .background(brush),
            state = listState,
            reverseLayout = true
        ) {
            // 原有LazyColumn内容保持不变
            item {
                if (screenState.isLoading) ProgressIndicator()
            }
            items(count = messages.size) { index ->
                ChatItem(messages[index], component.dateFormat)
            }
        }

        // 分页加载逻辑保持不变
        if (!listState.isScrollInProgress) {
            if (!listState.canScrollForward && listState.canScrollBackward && component.needNextPage)
                component.getNextPage()
        }

        // 输入框区域保持不变
        CommentRow(
            modifier = Modifier.fillMaxWidth(),
            interactionSource = commentInteractionSource,
            currentText = screenState.messageText ?: "",
            sendEnabled = true,
            onTextChange = { newText -> component.onEvent(ChatRoomEvents.MessageTextChanged(newText)) },
            onSendClick = { component.onEvent(ChatRoomEvents.SendMessage) }
        )
    }
}

3. 调整主Activity聊天页面的底部导航栏状态

确保聊天页面加载时隐藏底部导航栏,避免额外布局干扰:

// 主Activity中ChatRoomChild的处理分支
is RootComponent.Child.ChatRoomChild -> {
    showBottomBar = false // 隐藏底部导航栏
    ChatRoomScreen(instance.component)
}

关键原理

  • 将TopAppBar放在独立的固定层级,脱离受键盘调整影响的内容区域,确保其始终停留在屏幕顶部。
  • 让LazyColumn通过weight(1f)占据剩余空间,当键盘弹出时,adjustResize会自动缩小该区域的高度,实现仅消息列表适配键盘的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:19:56