Skip to content

Instantly share code, notes, and snippets.

@vincevargadev
Last active February 6, 2021 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vincevargadev/5e2a8558d496fecd518b7846ba5995b7 to your computer and use it in GitHub Desktop.
Save vincevargadev/5e2a8558d496fecd518b7846ba5995b7 to your computer and use it in GitHub Desktop.
Flutter SnackBar layout demos
// This gist is part of the https://github.com/dartsidedev/gists repository.
// There, you'll find further information about this gist.
// https://github.com/dartsidedev/gists#5e2a8558d496fecd518b7846ba5995b7
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Gists',
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('Snack Bar Demo'),
),
body: SnackBarDemoList(),
),
);
}
}
class SnackBarDemoList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: [
Demo(
'This is the basic SnackBar widget from the material library. '
'It is launched using the ScaffoldMessenger. '
'The passed-in content is a simple Text widget.',
OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Simple snack bar'),
),
);
},
child: const Text('Simple'),
),
),
Demo(
'This is the basic SnackBar from the material library, launched using the ScaffoldMessenger, with the behavior set to "floating".',
OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Floating snack bar'),
behavior: SnackBarBehavior.floating,
),
);
},
child: const Text('Floating'),
),
),
Demo(
'You can specify the action that the user can take based on the snack bar.\n\n'
'For example, the snack bar might let the user undo the operation that prompted the snackbar. Snack bars can have at most one action.\n\n'
'The action should not be "dismiss" or "cancel".\n\n'
'Notice how the snack bar automatically disappears when you tap on the snack bar action.',
OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Snack bar with "undo" action.'),
action: SnackBarAction(
label: 'Undo',
onPressed: () => print('TODO: handle "undo".'),
),
),
);
},
child: const Text('Snack bar with action'),
),
),
Demo(
'The snack bar action is positioned next to the snack bar content.\n\n'
'The snack bar content (if it is a Text widget) will automatically wrap.',
OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'This snack bar has a very long text content, that will let us see how the snack bar action is displayed.'),
action: SnackBarAction(
label: 'Undo',
onPressed: () => print('TODO: handle "undo".'),
),
),
);
},
child: const Text('Snack bar with action and long text'),
),
),
Demo(
'If a snack bar content and action label are very long, they can mess up the snack bar layout.',
OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'This snack bar has a very long action label and text content, that will let us see how the snack bar behaves under these special circumstances.'),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: 'Long action that might break the layout.',
onPressed: () => print('TODO: handle action.'),
),
),
);
},
child: const Text('Snack bar with long action and content'),
),
),
Demo(
'The Material Design on Snackbars recommends to display the action in its own line if the action or content are too long.\n\n'
'Unfortunately, if you just put the snack bar action in the content section, the snack bar action will be not themed correctly.',
OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'This snack bar has a very long action label and text content. Notice how the snack bar action theme is off.'),
SnackBarAction(
label: 'Long action placed in content.',
onPressed: () => print('TODO: handle action.'),
),
],
),
behavior: SnackBarBehavior.floating,
),
);
},
child: const Text('Snack bar with action placed in the content.'),
),
),
Demo(
'With some copying and pasting from the framework and some further tweaking we can fix this, but at this point you should ask yourself if the snack bar is the right choice for this message.\n\n'
'Alternatively, think about how you could phrase the same message succinctly.',
OutlinedButton(
onPressed: () {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
final bool isThemeDark = theme.brightness == Brightness.dark;
final Color buttonColor = isThemeDark
? colorScheme.primaryVariant
: colorScheme.secondary;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'This snack bar has a very long action label and text content. We fixed the action label, but at what price?'),
Align(
alignment: Alignment.centerRight,
child: TextButtonTheme(
data: TextButtonThemeData(
style: TextButton.styleFrom(
primary: buttonColor,
),
),
child: SnackBarAction(
label: 'Long action placed in content.',
onPressed: () => print('TODO: handle action.'),
),
),
),
],
),
behavior: SnackBarBehavior.floating,
),
);
},
child: const Text('Snack bar with action placed in the content.'),
),
),
],
);
}
}
class Demo extends StatelessWidget {
final String description;
final Widget example;
const Demo(
this.description,
this.example, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
const padding = EdgeInsets.fromLTRB(8, 8, 8, 8);
return Column(
children: [
Padding(
padding: padding,
child: Text(description),
),
example,
SizedBox(height: 8),
Divider(),
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment