Reputation: 685
In my code I call a bottom sheet to display a list of tiles. These tiles contain buttons that display a snackbar. That functionality works fine, the only issue is that the snackbar is displayed behind the bottom sheet so you can only see it if you close the bottom sheet. Each of them are called with the following code:
1. Bottom Sheet:
void _settingModalBottomSheet(context, stream, scaffoldKey ) {
if (_availableRides.length == 0) {
return null;
} else {
return scaffoldKey.currentState.showBottomSheet((context) {
return Column(
children: Widgets;
});
}
}
2. Snackbar
widget.scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("Created", textAlign:
TextAlign.center,),),
Does anyone know how I can position the snackbar in front of the bottom sheet
Upvotes: 40
Views: 34374
Reputation: 1983
Two conditions have to pass:
1. The bottomSheet
(the one that is supposed te be under the snackBar
) needs to have a Scaffold
widget
2. That Scaffold
widget (or SnackBar
widget) needs to have a custom key
:
Examples:
[Scaffold's key]:
return const Scaffold(
key: Key('value'),
body: Placeholder(),
);
[SnackBar's key]:
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
key: Key('value'),
content: Text('Hello Snackbar!'),
),
);
Full example:
import 'package:flutter/material.dart';
void main() {
runApp(const SunflowerApp());
}
class SunflowerApp extends StatefulWidget {
const SunflowerApp({super.key});
@override
State<StatefulWidget> createState() {
return _SunflowerAppState();
}
}
class _SunflowerAppState extends State<SunflowerApp> {
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyScaffold(),
);
}
}
class MyScaffold extends StatelessWidget {
const MyScaffold({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sunflower'),
),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Center(
child: ButtonBar(
children: <Widget>[
TextButton(
child: const Text('Button 1'),
onPressed: () => showModalBottomSheet(
context: context,
builder: (context) => const BasicBottomSheet(),
)),
],
),
),
),
const SizedBox(height: 20),
],
),
),
);
}
}
class BasicBottomSheet extends StatelessWidget {
const BasicBottomSheet({super.key});
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Hello Snackbar!'),
),
);
});
return const Scaffold(
key: Key('value'),
body: Placeholder(),
);
}
}
Upvotes: -1
Reputation: 211
I solved this problem with idle solution but it works
The Solution by 3 steps:
1 Add SizedBox
and set the same height of BottomSheet
2 Add Scaffold
as child of SizedBox
3 Add Your BottomSheet
SizedBox(
height: ... ,// height of bottomSheet
child: Scaffold(
body: ... , // your bottomSheet
)
)
Upvotes: 6
Reputation: 10963
SnackBar
has a property
for this. It's called behavior
, you could do this:
SnackBar(
behavior: SnackBarBehavior.floating,
...
floating → const SnackBarBehavior
This behavior will cause SnackBar to be shown above other widgets in the Scaffold. This includes being displayed above a BottomNavigationBar and a FloatingActionButton.
See material.io/design/components/snackbars.html for more details.
Upvotes: 2
Reputation: 779
This is a working solution according to documentation. https://docs.flutter.dev/cookbook/design/snackbars
This example works with bottom sheets as well.
ScaffoldMessengerKey
.Scaffold
.Scaffold
with ScaffoldMessenger
.scaffoldMessengerKey
to ScaffoldMessenger
scaffoldMessengerKey.currentState?.showSnackBar(SnackBar());
Example:
final scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
// Any widget with button.
// (Bottom sheet also) - root widget must be ScaffoldMessenger.
ScaffoldMessenger(
key: scaffoldMessengerKey,
child: Scaffold(
body: Container(
child: ElevatedButton(
style: raisedButtonStyle,
onPressed: () {
scaffoldMessengerKey.currentState?.showSnackBar(
//SnackBar design.
SnackBar(
backgroundColor: Colors.white,
elevation: 8,
content: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Text(
'Simple snackbar text.',
style: FlutterFlowTheme.of(context).bodyText1
.override(fontFamily: 'Rubik',
fontWeight: FontWeight.w300,
lineHeight: 1.5,
),
),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Some code to undo the change.
},
),
duration: Duration(seconds: 5),
behavior: SnackBarBehavior.floating,
},
child: Text('Open snackbar over bottom sheet!'),
); //ElevatedButton
); //Container
); //Scaffold
); //ScaffoldMessenger
Note: With this approach you don't need to pass BuildContext.
If you don't want to register ScaffoldMessengerKey
.
You can show SnackBar like this: ScaffoldMessenger.of(context).showSnackBar(SnackBar());
Upvotes: 0
Reputation: 49
I arrived on pretty decent solution. I wrapped my bottom sheet in a Scaffold
, but I added it as the bottomSheet
parameter. While adding the Scaffold
, some trailing background will be added, so I just made its background transparent.
Scaffold(
backgroundColor: Colors.transparent,
bottomSheet: ...,
)
Upvotes: 3
Reputation: 19514
you can use flushbar package. I think this is the better option if need to use with bottomSheet.
context should be your page's context, not bottomsheet context
any event inside bottomSheet
CustomFlushBar().flushBar(text: 'Thank you for your payment!', context: context,duration: 2);
CustomFlushBar class
class CustomFlushBar {
void flushBar({int duration, @required String text, Color iconColor, IconData iconData, Color backgroundColor, @required BuildContext context}) async {
await dismiss();
Flushbar(
margin: EdgeInsets.all(8),
borderRadius: 8,
backgroundColor: backgroundColor ?? Palette.greenButton,
icon: Icon(iconData ?? Icons.done, color: iconColor ?? Palette.white),
flushbarStyle: FlushbarStyle.FLOATING,
message: text,
duration: Duration(seconds: duration ?? 3),
)..show(context);
}
Future<void> dismiss() async {
if (!Flushbar().isDismissed()) {
await Flushbar().dismiss();
}
}
}
Upvotes: -1
Reputation: 785
You can achieve this Simply by wrapping your BottomSheet widget with a Scaffold.
eg:
void _settingModalBottomSheet(context, stream, scaffoldKey ) {
if (_availableRides.length == 0) {
return null;
} else {
return scaffoldKey.currentState.showBottomSheet((context) {
return Scaffold(
body: Column(
children: Widgets;
})
);
}
}
Upvotes: 3
Reputation: 1192
I solved by Set (padding from bottom to SnackBar) As much as the height of the (bottomSheet : height) .
In This Case I Have This bottomSheet:
bottomSheet: Container(
child: RaisedButton(...),
width: MediaQuery.of(context).size.width,
height: AppBar().preferredSize.height * 0.85,
),
And This snackBar:
_scaffoldKey.currentState.showSnackBar(SnackBar(
padding:EdgeInsetsDirectional.only(
bottom:AppBar().preferredSize.height * 0.85),
backgroundColor: Colors.red,
duration: new Duration(milliseconds: 3000),
content: Text('ETC..'),
));
Upvotes: 1
Reputation: 641
I solved this by changing bottomSheet
to bottomNavigationBar
since the floating snack bar solution didn't work for me.
Upvotes: -1
Reputation: 685
So I was able to solve this by just adding another Scaffold() to my Bottom sheet and passing it a new scaffold key
Upvotes: 23