Overlays in Flutter: Getting Started

Learn Flutter’s own way to display overlays like popUps, modals and dialog boxes with the help of popUpRoutes. By Michael Malak.

4 (1) · 1 Review

Download materials
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Using Overlay Mixin to Edit a Note

You want to show SaveNotePage widget as an overlay when you tap on a note item. This page will let you edit and save the note.

To achieve this, first go to lib/ui/notes/widgets/note_item_widget.dart, and at the top of the page add an import of your newly created overlay mixin:

import '../../_shared/mixin/overlay_mixin.dart';

Now, you can use the mixin with the _NoteItemWidgetState as the following:

class _NoteItemWidgetState extends State<NoteItemWidget>
    with OverlayStateMixin { 
       ... 
    }

Here, you are extending your _NoteItemWidgetState class with state of NoteItemWidget and adding the OverlayStateMixin with a with keyword.

Replace the code at /// TODO 4: Create and use OverlayMixin to show SaveNotePage as an overlay with:

void onNoteTap() {
  // 1
  toggleOverlay(
    SaveNotePage(
      
      // 2
      noteToEdit: note,

      // 3
      onNoteSaved: (editedNote) {
        widget.onEdit(editedNote);
        removeOverlay();
      },
    ),
  );
}

Here’s the breakdown of the code:

  1. In the onNoteTap() function you call the toggleOverlay to display SaveNotePage as an overlay.
  2. You pass the displayed note as an argument to noteToEdit.
  3. You implement callback function when you tap the save button which takes the editedNote as a parameter. Call the widget.onEdit function which will save the editedNote that you’ve passed as a parameter. This will save the notes and then remove the overlay by calling removeOverlay function

Build and run. When you click a note item in the list, you’ll see the edit note overlay.

Todo 4 result

The edit overlay works as expected, but instead of closing the overlay when you tap your device’s back button, the app closes. You’ll solve this next.

App closes on native back press

Removing the Overlay on Native Back Press

Since you’re not using the Navigator to manage your overlay, the edit note overlay is not closed when you tap back on your device, even though you expect the modal to be closed.

While you’re in lib/ui/notes/widgets/note_item_widget.dart, replace the build function at /// TODO 5: Use [WillPopScope] and [isOverlayShown] to prevent popping the page when used with the Overlay with:

// 1
@override
Widget build(BuildContext context) => WillPopScope(
      onWillPop: () async {
        // 2
        if (isOverlayShown) {
          removeOverlay();
          return false;
        }
        return true;
      },
      child: buildListTile(),
    );

Here’s what you did:

  1. Wrap buildListTile() with WillPopScope. The WillPopScope is triggered when a pop action is taking place. This has a method onWillPop which pop’s a widget if the return is true and prevents the pop if the return is false.
  2. Implement onWillPop callback that vetos attempts to close the Route. When isOverlayShown is true, you remove the overlay by removeOverlay function and prevent closing the route by returning a false value, otherwise, you allow closing it.

Build and run. Now, when you click back, the edit note overlay should close.

Todo 5 result

Did you know: Draggable uses Overlay widget under the hood.

Confirming Before Editing Notes

Now that you have already viewed an overlay to edit a note item, you want to show another overlay on top of it to confirm editing before saving it to the cache.

Head to lib/ui/save_note/save_note_page.dart, and add the following imports at the top of the file:

import '../_shared/mixin/overlay_mixin.dart';
import 'widgets/save_note_confirmation_widget.dart';

You can now add OverlayStateMixin to _SaveNotePageState as follows:

class _SaveNotePageState extends State<SaveNotePage> with OverlayStateMixin {

Add the following getters to the body of code>_SaveNotePageState:

// 1
bool get hasChanges {

  // 2
  final isHeaderChanged = widget.noteToEdit?.header != note.header;
  final isTextChanged = widget.noteToEdit?.text != note.text;
  return isHeaderChanged || isTextChanged;
}

// 3
bool get isEditMode => widget.noteToEdit != null;
  1. Add a getter to get a bool if the note has been edited.
  2. Detect if either the header or the text body has been modified.
  3. If widget.noteToEdit is passed to the widget, then it’s in edit mode.

Replace the code beneath /// TODO 6: Check page has edits and show confirmation overlay before saving the edits with:

// 1
if (isEditMode && hasChanges) {
  toggleOverlay(
    SaveNoteConfirmationWidget(
      // 2
      onConfirm: () => widget.onNoteSaved(note),
      onCancel: removeOverlay,
    ),
  );
} else {
  // 3
  widget.onNoteSaved(note);
}

Here’s what’s happening above:

  1. In the conditionals, if the note is in edit mode and has been modified, you show an overlay displaying SaveNoteConfirmationWidget. This has two buttons; one to confirm the save and other to cancel the save.
  2. When you tap confirm button, you save the note by calling the onNoteSaved callback function and pass the edited note as a parameter. When you tap cancel, you remove the overlay by calling the removeOverlay function.
  3. In case you’re not in edit mode or the note has changes, you trigger onNoteSaved callback, the else part of the conditionals.

Build and run. When you edit a note and modify the text, you get a confirmation overlay before you save the edits.

Todo 6 result

Congratulations again, you have successfully created overlays in Flutter that you can use accordingly.

Where to Go From Here?

Download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.

You now have a deeper understanding of overlays in Flutter and, more importantly, when and how to use them. When you find the need, you can create your own PopupRoute or implement your own way of handling the Overlay widget.

Check out the following links to learn more about some of the concepts in this tutorial:

We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!