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

Flutter中使用flutter_screenutil如何避免聊天界面输入框被键盘遮挡

解决Flutter聊天界面键盘弹出时输入框被遮挡的问题

你的布局存在两个核心问题:一是ListView未被限制高度,会导致布局异常;二是未处理键盘弹出时的界面适配,从而遮挡底部输入框。以下是修复后的完整代码及关键说明:

修复后的布局代码

Scaffold(
  // 确保Scaffold自动适配键盘高度,默认值为true,若手动设为false需改回
  resizeToAvoidBottomInset: true,
  body: Column(
    children: [
      // 用Expanded包裹ListView,让它占据输入栏以外的所有空间
      Expanded(
        child: ListView.builder(
          itemCount: controller.messages.length,
          itemBuilder: (BuildContext context, int index) {
            final item = controller.messages[index];
            return Message(
              msg: item.message.toString(),
              direction: index % 2 == 0 ? 'left' : 'right',
            );
          },
        ),
      ),
      // 输入栏布局,给TextInput加Expanded避免Row溢出
      Row(
        children: [
          Icon(Icons.add),
          Expanded(
            child: TextInput(
              controller: controller.textController,
              hint: 'Write Here',
              border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(35))),
            ),
          ),
          IconButton(
            onPressed: () => controller.sendMessage(),
            icon: Icon(Icons.send, color: kPrimaryColor),
          )
        ],
      ),
    ],
  ),
)

关键修改点

  • Expanded包裹ListView:限制ListView的高度为Column剩余空间,既解决布局异常问题,又让输入栏固定在底部。
  • Expanded包裹TextInput:避免Row因TextInput宽度不足出现布局溢出错误。
  • Scaffold的resizeToAvoidBottomInset:自动调整界面高度,确保键盘弹出时输入框不会被遮挡。

极端场景适配(消息过多时)

如果聊天消息过多,希望键盘弹出后仍能滚动查看历史消息,可以用SingleChildScrollView包裹整个Column:

Scaffold(
  resizeToAvoidBottomInset: true,
  body: SingleChildScrollView(
    // 禁用外层滚动,让内部ListView负责消息滚动
    physics: NeverScrollableScrollPhysics(),
    child: Column(
      children: [
        Expanded(
          child: ListView.builder(
            // 让ListView根据内容自适应高度
            shrinkWrap: true,
            itemCount: controller.messages.length,
            itemBuilder: (BuildContext context, int index) {
              final item = controller.messages[index];
              return Message(
                msg: item.message.toString(),
                direction: index % 2 == 0 ? 'left' : 'right',
              );
            },
          ),
        ),
        Row(
          children: [
            Icon(Icons.add),
            Expanded(
              child: TextInput(
                controller: controller.textController,
                hint: 'Write Here',
                border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(35))),
              ),
            ),
            IconButton(
              onPressed: () => controller.sendMessage(),
              icon: Icon(Icons.send, color: kPrimaryColor),
            )
          ],
        ),
      ],
    ),
  ),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:25:28