I’m unable to show the ModalBottomSheet on top of they keyboard input. Currently the keyboard opens and hides the fields in the back. I have used padding with MediaQuery as seen in other questions but that does not work for me.
Here is the snippet for the ModalBottomSheet:
void _showLoginModal(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: false,
enableDrag: false,
backgroundColor: Colors.transparent,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: FractionallySizedBox(
heightFactor: 0.4,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: LoginPage(),
),
),
);
},
);
}
Now here is the code for the login_page.dart fields:
@override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 20),
Row(
children: [
Expanded(
child: TextField(
controller: firstNameController,
decoration: _buildInputDecoration('First Name'),
textCapitalization: TextCapitalization.words,
),
),
SizedBox(width: 20),
Expanded(
child: TextField(
controller: lastNameController,
decoration: _buildInputDecoration('Last Name'),
textCapitalization: TextCapitalization.words,
),
),
],
),
SizedBox(height: 10),
TextField(
controller: phoneNumberController,
decoration: _buildInputDecoration('10 digit Mobile Number'),
keyboardType: TextInputType.phone,
maxLength: 10,
enabled: !isOtpSent,
),
SizedBox(height: 10),
if (isOtpSent)
TextField(
controller: otpController,
decoration: _buildInputDecoration('Enter OTP'),
keyboardType: TextInputType.number,
),
SizedBox(height: 10),
ElevatedButton.icon(
onPressed: () {
if (isOtpSent) {
verifyOtp();
} else {
sendOtp();
}
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xFF0194FE)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
icon: Icon(Icons.send, color: Colors.white),
label: Text(
isOtpSent ? 'Verify OTP' : 'Send OTP',
style: TextStyle(color: Colors.white),
),
),
],
),
),
);
}
2
Answers
Here’s a working example of a modal bottom sheet that is aware of the soft keyboard. It is set to take a percentage of the screen’s height (70%) but of course it can be adapted to have different sizes relative to
viewInsets.bottom
which represents the height of the soft keyboard even during animation.Also, this example assumes that you want to show scrollable content in the bottom modal sheet.
Recipe summary:
showModalBottomSeet
withisScrollControlled: true
builder
returns aSafeArea
with aPadding
wherebottom
is at leastviewInsets.bottom
. You can add an extra value here if you need.Padding
is aSizedBox
specifying the desiredheight
of the scroll viewport. You can play with this value if for example you want the bottom sheet to appear as it is lifted when the keyboard opens. Again, in this example theheight
is computed so that modal’s height stays constant whether the soft keyboard is open or closed.