How to make Modal Bottom Sheet elevated equally with Bottom App Bar in Flutter?
A solution would be to have the BottomAppBar in other ascendant Scaffold in your widget tree.
Reduced example:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold( // Your Ascendant Scaffold
body: MyScreen(),
bottomNavigationBar: MyBottomAppBar() // Your BottomAppBar here
),
);
}
}
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold( // Your descendant Scaffold
body: Center(
child: Text('Hello world'),
),
);
}
}
Complete example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyWidget(),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Item 1',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Item 2',
),
],
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Builder(
builder: (context) => ElevatedButton(
child: Text('Show modal bottom sheet'),
onPressed: () => _displaysBottomSheet(context),
),
),
),
);
}
void _displaysBottomSheet(BuildContext context) {
Scaffold.of(context).showBottomSheet(
(context) => Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)
],
),
),
),
);
}
}
Renaldi Arlin
Updated on December 01, 2022Comments
-
Renaldi Arlin over 1 year
So, I am a new Flutter Developer and currently trying to make my own flutter app without any tutorial. I am confused with the elevation of the Modal Bottom Sheet and Bottom App Bar. I want both of the widgets to be elevated equally. Currently, my app behavior is like this.. The Bottom Modal Sheet just covers the Bottom App Bar and everything else. My code is something like this.
home_screen.dart (where my Bottom Modal Sheet, FAB, Bottom App Bar is)
// Packages import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:moneige/models/transaction.dart'; // UIs import '../ui/home_screen/app_bar_title.dart'; import '../ui/home_screen/bottom_app_bar.dart'; import '../ui/home_screen/transaction_list_view.dart'; // Widgets import '../widget/add_button.dart'; // Styles import '../constants/styles.dart' as Styles; class HomeScreen extends StatelessWidget { final int totalBalance = 100000; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.white, title: MyAppBarTitle(totalBalance: totalBalance), ), body: ValueListenableBuilder( valueListenable: Hive.box('transactions').listenable(), builder: (context, transactionBox, widget) { return (transactionBox.length > 0) ? TransactionListView(transactionBox: transactionBox) : Center( child: Text('You have no transaction yet', style: Styles.textMedium)); }, ), bottomNavigationBar: MyBottomAppBar(), floatingActionButton: AddButton(() { Hive.box('transactions').add(Transaction( date: DateTime.now(), changes: 123000, notes: 'Crazier than usual')); showModalBottomSheet( shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)), ), backgroundColor: Colors.white, context: context, elevation: 10, useRootNavigator: true, builder: (BuildContext context) { return Container(height: 200); }); }), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, ); } }
bottom_app_bar.dart (where MyBottomAppBar is)
// Packages import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; // Widgets import '../../widget/settings_button.dart'; import '../../widget/transaction_report_switch.dart'; // Styles import '../../constants/styles.dart' as Styles; class MyBottomAppBar extends StatelessWidget { const MyBottomAppBar({ Key key, }) : super(key: key); @override Widget build(BuildContext context) { return BottomAppBar( shape: CircularNotchedRectangle(), color: Styles.colorPrimary, child: Row( children: [ Spacer(), Container( child: TransactionReportSwitch(() => Hive.box('transactions').deleteAll(Hive.box('transactions').keys)), ), Container( child: SettingsButton(), ), ], ), ); } }
add_button.dart (where AddButton is)
// Packages import 'package:flutter/material.dart'; // Styles import '../constants/styles.dart' as Styles; class AddButton extends StatelessWidget { final Function handler; AddButton(this.handler); @override Widget build(BuildContext context) { return FloatingActionButton( child: Icon( Icons.add_rounded, color: Colors.white, size: 28, ), backgroundColor: Styles.colorPrimary, focusColor: Colors.white12, hoverColor: Colors.white12, foregroundColor: Colors.white12, splashColor: Colors.white24, onPressed: handler, ); } }
I saw a really good animated FAB, Modal Bottom Sheet, and Bottom App Bar composition in the Flutter Gallery app, Reply example. . (https://play.google.com/store/apps/details?id=io.flutter.demo.gallery&hl=en) When the Modal Bottom Sheet appears, the FAB disappears animatedly and the Sheet and App Bar are equally elevated, also the Sheet is above the Bottom App Bar. This is the behavior I wanted in my app, do you guys have any solution?