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

Flutter Alert Dialog聚焦输入框时RenderFlex底部溢出问题求助

Flutter AlertDialog 输入框聚焦时底部溢出问题

我是Flutter新手,开发应用时在Expanded父组件下放置了多个子组件,点击其中一个组件会弹出带输入框的AlertDialog。但聚焦输入框时出现RenderFlex overflowed by 92 pixels on the bottom错误,已经用SingleChildScrollView包裹AlertDialog但问题依旧。

父组件代码

///--------父组件代码------------------------
Expanded(
  // flex: 1,
  // child: SingleChildScrollView(
  child: Container(
      padding: const EdgeInsets.all(0),
      // height: 100,
      color: Colors.white,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Column(
            children: [
              SingleChildScrollView(
                  child: FutureBuilder(
                future: getData(),
                builder: (context, snapshot) {
                  return snapshot.hasData
                      ? Column(
                          children: [
                            Container(
                              padding:
                                  const EdgeInsets.fromLTRB(10, 70, 0, 10),
                              child: const Text("选择穿梭车ID",
                                  style:
                                      TextStyle(fontWeight: FontWeight.bold)),
                            ),
                            Container(
                                padding:
                                    const EdgeInsets.fromLTRB(20, 0, 0, 10),
                                child: DropdownButton<String>(
                                    hint: const Text("选择穿梭车ID"),
                                    value: dropdownValue,
                                    icon: const Icon(Icons.arrow_downward),
                                    elevation: 16,
                                    style: const TextStyle(
                                        color: Colors.deepPurple),
                                    underline: Container(
                                      height: 2,
                                      width: 50,
                                      color: Colors.deepPurpleAccent,
                                    ),
                                    onChanged: (String? value) {
                                      setState(() {
                                        dropdownValue = value!;
                                        print(
                                            '已选择:  $dropdownValue');
                                        filterData(dropdownValue);
                                        // print(list);
                                      });
                                    },
                                    items: getListData()))
                          ],
                        )
                      : const Center(
                          child: CircularProgressIndicator(
                            strokeWidth: 3,
                          ),
                        );
                },
              )),
              Row(
                children: [
                  Container(
                      // height: 10,
                      padding: const EdgeInsets.fromLTRB(70, 50, 10, 0),
                      child: Wrap(children: [
                        InkWell(
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Container(
                                width: 50,
                                height: 50,
                                child: Image.asset(
                                    'assets/images/home-page.png'),
                              ),
                              const SizedBox(
                                height: 10,
                              ),
                              const Text(
                                '首页',
                                style: TextStyle(
                                    color: Colors.black,
                                    fontWeight: FontWeight.bold),
                              ),
                            ],
                          ),
                          onTap: () {
                            GetHome(context);
                          },
                        ),
                      ])),
                  Container(
                      padding: const EdgeInsets.fromLTRB(30, 70, 10, 10),
                      child: Column(
                        children: [
                          Container(
                            child: BatteryIndicator(
                              batteryFromPhone: false,
                              batteryLevel: batteryLevel,
                              style: BatteryIndicatorStyle.values[0],
                              colorful: true,
                              showPercentNum: true,
                              mainColor: Colors.blue,
                              size: 25.0,
                              ratio: 4.0,
                              showPercentSlide: true,
                            ),
                          ),
                          const SizedBox(
                            height: 25,
                          ),
                          const Text(
                            '电量',
                            style: TextStyle(fontWeight: FontWeight.bold),
                          )
                        ],
                      ))
                ],
              ),
              Row(
                children: [
                  Container(
                    height: 10,
                  )
                ],
              ),
              Row(
                children: [
                  Container(
                      // height: 10,
                      padding: const EdgeInsets.fromLTRB(40, 50, 10, 0),
                      child: Wrap(children: [
                        InkWell(
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Container(
                                width: 50,
                                height: 50,
                                child: Image.asset(
                                    'assets/images/inventory.png'),
                              ),
                              const SizedBox(
                                height: 10,
                              ),
                              const Text(
                                '库存检查',
                                style: TextStyle(
                                    color: Colors.black,
                                    fontWeight: FontWeight.bold),
                              )
                            ],
                          ),
                          onTap: () {
                            GetInventory(context);
                          },
                        ),
                      ])),
                  Container(
                      // height: 10,
                      padding: const EdgeInsets.fromLTRB(10, 50, 10, 0),
                      child: Wrap(children: [
                        InkWell(
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Container(
                                width: 50,
                                height: 50,
                                child:
                                    Image.asset('assets/images/distance.png'),
                              ),
                              const SizedBox(
                                height: 10,
                              ),
                              const Text(
                                '托盘距离',
                                style: TextStyle(
                                    color: Colors.black,
                                    fontWeight: FontWeight.bold),
                              ),
                            ],
                          ),
                          onTap: () {
                            EnterPalletDistance(context);
                          },
                        ),
                      ]))
                ],
              ),
              Row(
                children: [
                  Container(
                    height: 20,
                  )
                ],
              ),
              Row(
                children: [
                  Container(
                    // height: 100,
                    padding: const EdgeInsets.fromLTRB(90, 50, 10, 0),
                    child: Wrap(children: [
                      Material(
                        elevation: 20,
                        child: ElevatedButton(
                          child: Text('停止'),
                          style: ElevatedButton.styleFrom(
                              primary: Colors.red,
                              padding: const EdgeInsets.symmetric(
                                  horizontal: 50, vertical: 20),
                              textStyle: const TextStyle(
                                  fontSize: 15, fontWeight: FontWeight.bold)),
                          onPressed: () {
                            Stop(context);
                          },
                        ),
                      ),
                    ]),
                  )
                ],
              ),
            ],
          ),
        ],
      )),
  // )
);

问题演示

输入框聚焦时底部溢出演示

AlertDialog代码

///-------------------- AlertDialog代码--------------------
EnterPalletDistance(context) {
  final isSelected = CheckIfShuttleSelected(context);
  // print(isSelected);
  if (isSelected) {
    // print("CONTEXT IS: $context");
    TextEditingController palletDistanceController = TextEditingController();
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            // alignment: Alignment.topCenter,
            // scrollable: true,
            title: const Text('输入托盘距离'),
            content: SingleChildScrollView(
              child:
                  //  Column(
                  //   children: <Widget>[
                  // child:
                  Container(
                // height: 100,
                // padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                child: TextField(
                  onChanged: (value) {
                    // print(value);
                  },
                  controller: palletDistanceController,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: '输入距离',
                  ),
                ),
                //   ),
                // ],
              ),
            ),
            actions: <Widget>[
              TextButton(
                style: TextButton.styleFrom(
                    foregroundColor: Colors.white,
                    backgroundColor: Colors.red,
                    textStyle: const TextStyle(color: Colors.white)),
                child: const Text('取消'),
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
              TextButton(
                child: const Text('提交'),
                onPressed: () {
                  Navigator.pop(context);
                },
                style: TextButton.styleFrom(
                    foregroundColor: Colors.white,
                    backgroundColor: Colors.green),
              ),
            ],
          );
        })
}

解决方法

1. 启用AlertDialog的scrollable属性

AlertDialog自带滚动支持,开启scrollable: true即可自动处理内容在键盘弹出时的滚动,无需手动嵌套SingleChildScrollView:

return AlertDialog(
  scrollable: true, // 开启此属性
  title: const Text('输入托盘距离'),
  content: Container(
    child: TextField(
      onChanged: (value) {
        // print(value);
      },
      controller: palletDistanceController,
      decoration: const InputDecoration(
        border: OutlineInputBorder(),
        labelText: '输入距离',
      ),
    ),
  ),
  actions: <Widget>[
    // ... 原有按钮代码
  ],
);

2. 给父页面添加滚动能力

问题本质是键盘弹出时,父页面(Expanded下的内容)无法滚动导致布局挤压。给Expanded的子Container外层包裹SingleChildScrollView:

Expanded(
  child: SingleChildScrollView( // 添加此组件
    child: Container(
      padding: const EdgeInsets.all(0),
      color: Colors.white,
      child: Column(
        // ... 原有Column内容
      ),
    ),
  ),
);

3. 限制AlertDialog的最大高度

通过MediaQuery获取屏幕高度,限制Dialog内容区域的最大高度,避免溢出:

return AlertDialog(
  title: const Text('输入托盘距离'),
  content: SizedBox(
    height: MediaQuery.of(context).size.height * 0.3, // 限制为屏幕高度的30%
    child: SingleChildScrollView(
      child: TextField(
        // ... 输入框代码
      ),
    ),
  ),
  actions: <Widget>[
    // ... 原有按钮代码
  ],
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:30:17