Flutter中如何让showModalBottomSheet内的Form不被软键盘遮挡可滚动
问题解决方法
这个问题是showModalBottomSheet默认配置不支持软键盘适配导致的,只需要修改两处核心配置即可解决:
1. 调整showModalBottomSheet基础参数
添加两个核心参数:
isScrollControlled: true:允许底部弹窗高度自适应,跟随软键盘上浮useSafeArea: true:避免弹窗内容超出系统顶部安全区域
2. 给弹窗根组件添加软键盘适配边距
在builder返回的组件外层套Padding,底部边距取当前软键盘的高度MediaQuery.of(context).viewInsets.bottom,确保内容整体顶在软键盘上方。同时给Column设置mainAxisSize: MainAxisSize.min,让弹窗只占用表单需要的最小高度。
修改后完整代码
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; class UserScreen extends StatefulWidget { UserScreen({Key? key}) : super(key: key); @override _UserScreenState createState() => _UserScreenState(); } class _UserScreenState extends State<UserScreen> { void addNewProducts(BuildContext ctx) { showModalBottomSheet( context: ctx, // 新增两个适配参数 isScrollControlled: true, useSafeArea: true, builder: (_) { return GestureDetector( onTap: () {}, behavior: HitTestBehavior.opaque, // 新增Padding适配软键盘高度 child: Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(ctx).viewInsets.bottom, ), child: Card( child: SingleChildScrollView( child: Form( child: Column( // 适配最小高度 mainAxisSize: MainAxisSize.min, children: <Widget>[ const SizedBox(height: 20,), TextFormField( keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Product Name', icon: Icon(Icons.insert_chart)), ), TextFormField( keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Product Description', icon: Icon(Icons.description)), ), TextFormField( keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Minimum Bid Price', icon: Icon(Icons.price_check)), ), TextFormField( keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Auction End DateTime', icon: Icon(Icons.data_saver_off)), ), const SizedBox( height: 20, ), ElevatedButton( onPressed: () {}, child: const Text('Add Product'), ), const SizedBox(height: 20,), ], ), ), ), ), ), ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('User Screen'), actions: [ DropdownButton( items: [ DropdownMenuItem( value: 'logout', child: Row( children: <Widget>[ Icon( Icons.exit_to_app, color: Theme.of(context).indicatorColor, ), const SizedBox( width: 8, ), const Text('Logout') ], ), ), ], onChanged: (itemIdentifire) { if (itemIdentifire == 'logout') { FirebaseAuth.instance.signOut(); } }, ) ], ), body: const Card(), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, floatingActionButton: FloatingActionButton( child: const Icon(Icons.add), onPressed: () { addNewProducts(context); }, ), ); } }
问题场景参考截图
- 点击按钮唤起的初始表单界面:

- 原问题唤起软键盘后的遮挡效果:

修改完成后点击输入框时,弹窗会自动整体上浮到软键盘上方,内部表单支持滚动,不会再出现遮挡问题。
内容的提问来源于stack exchange,提问作者Md. Fazle Rabbi
相关产品推荐
相关产品推荐

