Kinda Code
Home/Flutter/Flutter Bottom Sheet: Tutorial & Examples

Flutter Bottom Sheet: Tutorial & Examples

Last updated: October 10, 2022

BottomSheet is a built-in widget in Flutter. This widget is very useful in many situations, such as when you want to present some information, display a menu, show a form with text fields, etc.

This article will walk you through 3 distinct examples of implementing BottomSheet in Flutter apps. The first one is about a modal bottom sheet, the second one is about a persistent bottom sheet and the last one is about using a modal bottom sheet with multiple text fields inside. The point of the third example is to solve a common realistic problem: the soft keyboard overlaps the text fields and therefore the user is made it difficult to enter information.

In general, modal bottom sheets are shown by using the showModalBottomSheet function.

Example Preview

The full code

// main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        // use Material 3
        useMaterial3: true,
        primarySwatch: Colors.blue,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  void _show(BuildContext ctx) {
    showModalBottomSheet(
        elevation: 10,
        backgroundColor: Colors.amber,
        context: ctx,
        builder: (ctx) => Container(
              width: 300,
              height: 250,
              color: Colors.white54,
              alignment: Alignment.center,
              child: const Text('Breathe in... Breathe out...'),
            ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: SafeArea(
        child: Center(
          child: ElevatedButton(
            child: const Text('Show The BottomSheet'),
            onPressed: () => _show(context),
          ),
        ),
      ),
    );
  }
}

Persistent Bottom Sheet

Note: This persistent bottom sheet remains visible even when the user interacts with other parts of the app. It isn’t a LocalHistoryEntry and cannot be dismissed with Navigator.of(context).pop() or the scaffold appBar’s back button.

Example Preview

The code

// main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        // enable Material 3
        useMaterial3: true,
        primarySwatch: Colors.blue,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _showBottomSheet = true;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Container(),

      // The bottom sheet here
      bottomSheet: _showBottomSheet
          ? BottomSheet(
              elevation: 10,
              backgroundColor: Colors.amber,
              enableDrag: false,
              onClosing: () {},
              builder: (BuildContext ctx) => Container(
                    width: double.infinity,
                    height: 250,
                    alignment: Alignment.center,
                    child: ElevatedButton(
                      child: const Text(
                        'Close this bottom sheet',
                      ),
                      onPressed: () {
                        setState(() {
                          _showBottomSheet = false;
                        });
                      },
                    ),
                  ))
          : null,
    );
  }
}

Example Preview

This example creates a modal bottom sheet with some text fields and a button that lets users submit some information. You will notice that when the soft keyboard shows up, the bottom sheet will move up too, so the text fields will not be covered.

Set the isScrollControlled parameter of the showModalBottomSheet function to true and add an extra padding-bottom equal to or greater than MediaQuery.of(context).viewInsets.bottom makes things work fine.

The full code

// main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  // This function is triggered when the floating buttion is pressed
  void _show(BuildContext ctx) {
    showModalBottomSheet(
        isScrollControlled: true,
        elevation: 5,
        context: ctx,
        builder: (ctx) => Padding(
              padding: EdgeInsets.only(
                  top: 15,
                  left: 15,
                  right: 15,
                  bottom: MediaQuery.of(ctx).viewInsets.bottom + 15),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const TextField(
                    keyboardType: TextInputType.name,
                    decoration: InputDecoration(labelText: 'Name'),
                  ),
                  const TextField(
                    keyboardType: TextInputType.number,
                    decoration: InputDecoration(labelText: 'Age'),
                  ),
                  const SizedBox(
                    height: 15,
                  ),
                  ElevatedButton(onPressed: () {}, child: const Text('Submit'))
                ],
              ),
            ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () => _show(context),
      ),
    );
  }
}

Wrap Up

This article walked you through a few examples of working with BottomSheet in Flutter. Continue learning more new and interesting stuff by taking a look at the following articles: Flutter and Firestore Database: CRUD example, Example of sortable DataTable in Flutter, Working with Time Picker in Flutter, Working with Cupertino Date Picker in Flutter, Working with AlertDialog in Flutter, Flutter & SQLite: CRUD Example.

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.