mirror of
https://github.com/material-components/material-components-flutter.git
synced 2026-01-16 10:01:47 +08:00
7.2 KiB
7.2 KiB
Snackbars
Snackbars provide brief messages about app processes at the bottom of the screen.
Contents
Using snackbars
Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and they don’t require user input to disappear.
Making snackbars accessible
A SnackBar with an action will not time out when TalkBack or VoiceOver are enabled. This is controlled by AccessibilityFeatures.accessibleNavigation.
Anatomy and key properties
The following is an anatomy diagram of a snackbar:
- Text label
- Container
- Action (optional)
Text label properties
| Property | |
|---|---|
| Text label | pass a Widget to content |
| Text color | pass a Widget to content |
| Typography | pass a Widget to content |
Container properties
| Property | |
|---|---|
| Color | backgroundColor |
| Elevation | elevation |
| Shape border | shape |
Action properties
| Property | |
|---|---|
| Color | color on action |
| Text label | label on action |
| Text color | textColor on action |
Snackbar example
SnackBar
The following is an example of a snackbar with an action button:
SnackBar(
behavior: SnackBarBehavior.floating,
content: Text('Text label'),
action: SnackBarAction(
label: 'Action',
onPressed: () {},
),
)
Theming example
SnackBar
The following is an example of a snackbar with an action button that uses the Material.io Shrine color theming::
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
home: SnackBarsDemo(),
theme: buildShrineTheme(),
);
}
}
class SnackBarsDemo extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Snackbars'),
actions: [SnackbarButton()],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'replace with url for snackbars-background.jpg after merge'),
fit: BoxFit.cover,
),
),
),
);
}
}
class SnackbarButton extends StatelessWidget {
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
final snackBar = SnackBar(
behavior: SnackBarBehavior.floating,
content: Text('Text label'),
action: SnackBarAction(
label: 'Action',
onPressed: () {},
),
);
// Find the Scaffold in the widget tree and use
// it to show a SnackBar.
Scaffold.of(context).showSnackBar(snackBar);
},
child: Text('Show SnackBar'),
);
}
}
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
colorScheme: _shrineColorScheme,
accentColor: shrineBrown900,
primaryColor: shrinePink100,
buttonColor: shrinePink100,
scaffoldBackgroundColor: shrineBackgroundWhite,
cardColor: shrineBackgroundWhite,
textSelectionTheme: TextSelectionThemeData(selectionColor: shrinePink100),
errorColor: shrineErrorRed,
buttonTheme: const ButtonThemeData(
colorScheme: _shrineColorScheme,
textTheme: ButtonTextTheme.normal,
),
primaryIconTheme: _customIconTheme(base.iconTheme),
textTheme: _buildShrineTextTheme(base.textTheme),
primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),
iconTheme: _customIconTheme(base.iconTheme),
);
}
IconThemeData _customIconTheme(IconThemeData original) {
return original.copyWith(color: shrineBrown900);
}
TextTheme _buildShrineTextTheme(TextTheme base) {
return base
.copyWith(
caption: base.caption.copyWith(
fontWeight: FontWeight.w400,
fontSize: 14,
letterSpacing: defaultLetterSpacing,
),
button: base.button.copyWith(
fontWeight: FontWeight.w500,
fontSize: 14,
letterSpacing: defaultLetterSpacing,
),
)
.apply(
fontFamily: 'Rubik',
displayColor: shrineBrown900,
bodyColor: shrineBrown900,
);
}
const ColorScheme _shrineColorScheme = ColorScheme(
primary: shrinePink100,
primaryVariant: shrineBrown900,
secondary: shrinePink50,
secondaryVariant: shrineBrown900,
surface: shrineSurfaceWhite,
background: shrineBackgroundWhite,
error: shrineErrorRed,
onPrimary: shrineBrown900,
onSecondary: shrineBrown900,
onSurface: shrineBrown900,
onBackground: shrineBrown900,
onError: shrineSurfaceWhite,
brightness: Brightness.light,
);
const Color shrinePink50 = Color(0xFFFEEAE6);
const Color shrinePink100 = Color(0xFFFEDBD0);
const Color shrinePink300 = Color(0xFFFBB8AC);
const Color shrinePink400 = Color(0xFFEAA4A4);
const Color shrineBrown900 = Color(0xFF442B2D);
const Color shrineBrown600 = Color(0xFF7D4F52);
const Color shrineErrorRed = Color(0xFFC5032B);
const Color shrineSurfaceWhite = Color(0xFFFFFBFA);
const Color shrineBackgroundWhite = Colors.white;
const defaultLetterSpacing = 0.03;



