Bottom sheets are a popular UI component in mobile app development that allows displaying additional content or actions from the bottom of the screen. Flutter, a versatile and powerful UI toolkit, provides various types of bottom sheets, including modal bottom sheets and persistent bottom sheets. In this blog post, we'll dive deep into modal bottom sheets in Flutter and explore their different use cases with examples.
1. BottomSheet constructor
The BottomSheet
widget in Flutter represents a bottom sheet that can be displayed temporarily and slides up from the bottom of the screen. The BottomSheet
constructor requires a context
and a builder
callback function that returns the content of the bottom sheet.
void _showModalBottomSheet(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( height: 200, child: Center( child: Text("Modal Bottom Sheet"), ), ); }, ); }
2. Modal Bottom Sheet
Modal bottom sheets are temporary bottom sheets that cover a portion of the screen and prevent interaction with the rest of the app until the user dismisses them. To create a modal bottom sheet, use the showModalBottomSheet
function, as shown in the previous example.
3. Persistent Bottom Sheet
Persistent bottom sheets are bottom sheets that remain visible on the screen, even when the user interacts with other parts of the app. To create a persistent bottom sheet, use the Scaffold
widget's bottomSheet
property.
Scaffold( appBar: AppBar( title: Text("Persistent Bottom Sheet Example"), ), body: Center( child: ElevatedButton( onPressed: () { _showPersistentBottomSheet(context); }, child: Text("Show Persistent Bottom Sheet"), ), ), bottomSheet: Container( height: 200, color: Colors.blue, child: Center( child: Text("Persistent Bottom Sheet"), ), ), );
4. Modal Bottom Sheet with Text Fields inside
Modal bottom sheets often contain form fields for input or any other interactive elements. Let's create a modal bottom sheet with text fields inside.
void _showModalBottomSheetWithTextFields(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( padding: EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text("Enter your details"), TextFormField( decoration: InputDecoration(labelText: "Name"), ), TextFormField( decoration: InputDecoration(labelText: "Email"), ), ElevatedButton( onPressed: () { // Process form data Navigator.pop(context); }, child: Text("Submit"), ), ], ), ); }, ); }
5. Modal Bottom Sheet with ListTile inside
Sometimes, you might want to display a list of options inside a modal bottom sheet. Flutter's ListTile
widget is an excellent choice for this purpose.
void _showModalBottomSheetWithListTile(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( child: ListView( shrinkWrap: true, children: [ ListTile( leading: Icon(Icons.camera), title: Text("Camera"), onTap: () { // Handle camera selection Navigator.pop(context); }, ), ListTile( leading: Icon(Icons.photo), title: Text("Gallery"), onTap: () { // Handle gallery selection Navigator.pop(context); }, ), ], ), ); }, ); }
Source Code
Sure! Let's create a simple Flutter app that demonstrates all the varieties of bottom sheets we discussed in the blog post. This app will have buttons for each type of bottom sheet, and when you tap on a button, the corresponding bottom sheet will be displayed.
Here's the example app code:
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.green.shade900), useMaterial3: true, ), home: Scaffold( appBar: AppBar( title: const Text( "FlutterforGeeks", style: TextStyle(color: Colors.green), ), ), body: BottomSheetVarietiesApp(), ), ); } } class BottomSheetVarietiesApp extends StatelessWidget { void _showModalBottomSheet(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( height: 200, child: const Center( child: Text("Modal Bottom Sheet"), ), ); }, ); } void _showPersistentBottomSheet(BuildContext context) { Scaffold.of(context).showBottomSheet( (BuildContext context) { return Container( height: 200, color: Colors.green, child: const Center( child: Text("Thanks For Watching Subscribe for more videos"), ), ); }, ); } void _showModalBottomSheetWithTextFields(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text("Enter your details"), TextFormField( decoration: const InputDecoration(labelText: "Name"), ), TextFormField( decoration: const InputDecoration(labelText: "Email"), ), ElevatedButton( onPressed: () { // Process form data Navigator.pop(context); }, child: const Text("Submit"), ), ], ), ); }, ); } void _showModalBottomSheetWithListTile(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( child: ListView( shrinkWrap: true, children: [ ListTile( leading: const Icon(Icons.camera), title: const Text("Camera"), onTap: () { // Handle camera selection Navigator.pop(context); }, ), ListTile( leading: const Icon(Icons.photo), title: const Text("Gallery"), onTap: () { // Handle gallery selection Navigator.pop(context); }, ), ], ), ); }, ); } @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { _showModalBottomSheet(context); }, child: const Text("Show Modal Bottom Sheet"), ), const SizedBox(height: 16), ElevatedButton( onPressed: () { _showPersistentBottomSheet(context); }, child: const Text("Show Persistent Bottom Sheet"), ), const SizedBox(height: 16), ElevatedButton( onPressed: () { _showModalBottomSheetWithTextFields(context); }, child: const Text("Modal Bottom Sheet with Text Fields"), ), const SizedBox(height: 16), ElevatedButton( onPressed: () { _showModalBottomSheetWithListTile(context); }, child: const Text("Modal Bottom Sheet with List Tile"), ), ], ), ); } }
Copy and paste this code into your Flutter project, and it will create an app that showcases all the different types of bottom sheets. When you run the app, you'll see buttons for each bottom sheet type, and tapping on each button will display the respective bottom sheet on the screen.
Remember to add the necessary dependencies and imports to your pubspec.yaml
file and the top of the Dart file. Also, make sure to wrap the BottomSheetVarietiesApp
widget with a Builder
widget to provide a BuildContext
for the bottom sheet functions to work correctly.
Video Demo
Conclusion
Bottom sheets are a fantastic way to display additional information or actions in a mobile app without obstructing the main content. Flutter provides powerful support for modal and persistent bottom sheets, making it easy to implement various UI patterns.
In this blog post, we covered the basics of creating modal bottom sheets using the showModalBottomSheet
function and demonstrated how to create both simple and interactive modal bottom sheets with text fields and list tiles. Remember that bottom sheets enhance user experience and can be customized to match the app's overall design and theme.
You can find the complete example code for each type of bottom sheet in the official Flutter documentation and on the Flutter website. Feel free to experiment with different widgets and layouts to create compelling bottom sheets that meet your app's specific needs.
Happy coding with Flutter! 🚀