How can I show a floating button over all pages in Flutter?

Viewed 778

I would like to keep showing a floating button or widget in Flutter even though the page is changed by Navigator.of(context).push() like mini music player which placed in the bottom.

How can I implement that ??

enter image description here

1 Answers

You can extract the scaffold as a layout that contains a bottom sheet, and use this layout in every page you build, passing in the title, body, etc., so that the bottom sheet is persistent in all pages. Snippet below.

Persistent Bottom Sheet

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Persistent Bottom Sheet',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        brightness: Brightness.dark,
      ),
      initialRoute: "/",
      routes: {
        "/": (context) => Home(),
        "/library": (context) => Library(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Layout(
      title: "Home",
      body: Center(
        child: Text("Home"),
      ),
      actions: <Widget>[
        InkWell(
          onTap: () {
            Navigator.of(context).pushNamed("/library");
          },
          child: Tooltip(
            message: "Go To Library",
            child: Padding(
              padding: const EdgeInsets.all(12),
              child: Icon(Icons.library_music),
            ),
          ),
        )
      ],
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Layout(
      title: "Library",
      body: Center(
        child: Text("Library"),
      ),
    );
  }
}

class Layout extends StatelessWidget {
  final String title;
  final Widget body;
  final List<Widget>? actions;

  const Layout({
    Key? key,
    required this.title,
    required this.body,
    this.actions,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text(title),
        actions: actions,
      ),
      body: body,
      bottomSheet: Container(
        width: double.infinity,
        padding: const EdgeInsets.all(15),
        color: Theme.of(context).cardColor,
        child: Text("Persistent Bottom Sheet"),
      ),
    );
  }
}
Related