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

Flutter:解决AlertDialog中TextFormField弹出键盘时的溢出问题

解决AlertDialog弹出键盘时的溢出问题

问题场景

使用AlertDialog让用户输入新建训练名称时,弹出键盘后Widget出现滚动并溢出的情况,效果如下:

AlertDialog上的溢出效果

用户的实现代码:

showDialog(
    context: context,
    builder: (context) {
      TextEditingController titleController = TextEditingController();
      return AlertDialog(
        title: const Text("Workout Title"),
        content: SizedBox(
          height: 110,
          child: Column(
            children: [
              TextFormField(
                  focusNode: _focusNode,
                  controller: titleController,
                  inputFormatters: [
                    LengthLimitingTextInputFormatter(14),
                  ]),
              Padding(
                padding: const EdgeInsets.only(top: 10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    TextButton(
                        onPressed: () => Navigator.pop(context),
                        child: const Text("CANCEL")),
                    TextButton(
                        onPressed: () async {
                          setState(() {
                            if (titleController.text.isNotEmpty) {
                              dayTiles.add(
                                  DayTile(title: titleController.text));
                            }
                          });
                          FocusScope.of(context).requestFocus(FocusNode());
                          saveData();
                          Navigator.pop(context);
                        },
                        child: const Text("DONE")),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
    });

解决方案

1. 移除固定高度容器并设置Column自适应

问题核心是给content设置了固定高度的SizedBox,弹出键盘后可用空间缩小,固定高度会强制布局保持原有尺寸,导致溢出。直接移除固定高度,同时给Column添加mainAxisSize: MainAxisSize.min,让它仅占用内容所需的最小高度:

showDialog(
    context: context,
    builder: (context) {
      TextEditingController titleController = TextEditingController();
      return AlertDialog(
        title: const Text("训练名称"),
        content: Column(
          mainAxisSize: MainAxisSize.min, // 让Column自适应内容高度
          children: [
            TextFormField(
                focusNode: _focusNode,
                controller: titleController,
                inputFormatters: [
                  LengthLimitingTextInputFormatter(14),
                ]),
            Padding(
              padding: const EdgeInsets.only(top: 10),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  TextButton(
                      onPressed: () => Navigator.pop(context),
                      child: const Text("取消")),
                  TextButton(
                      onPressed: () async {
                        setState(() {
                          if (titleController.text.isNotEmpty) {
                            dayTiles.add(DayTile(title: titleController.text));
                          }
                        });
                        FocusScope.of(context).requestFocus(FocusNode());
                        saveData();
                        Navigator.pop(context);
                      },
                      child: const Text("确定")),
                ],
              ),
            ),
          ],
        ),
      );
    });

2. 可选:添加滚动容器保障极端场景

如果担心内容在小屏设备上仍有溢出风险,可以用SingleChildScrollView包裹Column,确保内容可滚动:

showDialog(
    context: context,
    builder: (context) {
      TextEditingController titleController = TextEditingController();
      return AlertDialog(
        title: const Text("训练名称"),
        content: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextFormField(
                  focusNode: _focusNode,
                  controller: titleController,
                  inputFormatters: [
                    LengthLimitingTextInputFormatter(14),
                  ]),
              Padding(
                padding: const EdgeInsets.only(top: 10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    TextButton(
                        onPressed: () => Navigator.pop(context),
                        child: const Text("取消")),
                    TextButton(
                        onPressed: () async {
                          setState(() {
                            if (titleController.text.isNotEmpty) {
                              dayTiles.add(DayTile(title: titleController.text));
                            }
                          });
                          FocusScope.of(context).requestFocus(FocusNode());
                          saveData();
                          Navigator.pop(context);
                        },
                        child: const Text("确定")),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
    });

关键说明

  • mainAxisSize: MainAxisSize.min:是让AlertDialog内容自适应的核心,避免Column占用多余空间。
  • 固定高度会破坏AlertDialog的自适应布局逻辑,键盘弹出时可用空间变化,固定高度容易引发布局冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:22:56