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
相关产品推荐
相关产品推荐

