When working with Flutter, one common UI requirement is to have a BottomSheet move along with the keyboard. This can be particularly useful when you have a TextField within the BottomSheet that is autofocused. In this article, we’ll discuss how to achieve this using the isScrollControlled
property and proper padding with MediaQuery
.
To ensure a smooth user experience, we need to configure the BottomSheet to be scrollable and adjust its padding dynamically based on the keyboard’s visibility. Here’s how you can implement this in your Flutter app.
Implementing the Solution
- Enable Scroll Control: The
isScrollControlled
property of theshowModalBottomSheet
function must be set totrue
. This allows the BottomSheet to take full height and be scrollable. - Adjust Padding: Use
MediaQuery.of(context).viewInsets
to set the padding for the BottomSheet. This adjusts the padding based on the current view insets, effectively moving the BottomSheet with the keyboard.
Here’s a step-by-step implementation:
Step 1: Create the BottomSheet
Firstly, we need to create a method that shows the BottomSheet. In this method, we will set isScrollControlled
to true
and apply the necessary padding.
void _showBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true, // Enable scroll control
builder: (context) {
return Padding(
padding: MediaQuery.of(context).viewInsets, // Adjust padding for keyboard
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
autofocus: true, // Autofocus the text field
decoration: InputDecoration(
hintText: 'Type something...',
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Close'),
),
],
),
),
);
},
);
}
Step 2: Trigger the BottomSheet
Now, you need a button or any other widget to trigger the BottomSheet. Here’s an example with a simple button:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BottomSheet with Keyboard'),
),
body: Center(
child: ElevatedButton(
onPressed: () => _showBottomSheet(context),
child: Text('Show BottomSheet'),
),
),
);
}
Complete Example
Here’s how you can integrate the above methods into a complete Flutter app:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
void _showBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
autofocus: true,
decoration: InputDecoration(
hintText: 'Type something...',
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Close'),
),
],
),
),
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BottomSheet with Keyboard'),
),
body: Center(
child: ElevatedButton(
onPressed: () => _showBottomSheet(context),
child: Text('Show BottomSheet'),
),
),
);
}
}
By setting isScrollControlled
to true
and adjusting the padding using MediaQuery.of(context).viewInsets
, you can ensure that your BottomSheet moves along with the keyboard, providing a smooth and intuitive user experience. This approach is simple yet effective for handling BottomSheets with text inputs in Flutter.
Leave a Reply