SegmentedButton<T> class
A Material button that allows the user to select from limited set of options.
Segmented buttons are used to help people select options, switch views, or sort elements. They are typically used in cases where there are only 2-5 options.
The options are represented by segments described with ButtonSegment entries in the segments field. Each segment has a ButtonSegment.value that is used to indicate which segments are selected.
The selected field is a set of selected ButtonSegment.values. This should be updated by the app in response to onSelectionChanged updates.
By default, only a single segment can be selected (for mutually exclusive choices). This can be relaxed with the multiSelectionEnabled field.
Like ButtonStyleButtons, the SegmentedButton's visuals can be configured with a ButtonStyle style field. However, unlike other buttons, some of the style parameters are applied to the entire segmented button, and others are used for each of the segments.
By default, a checkmark icon is used to show selected items. To configure this behavior, you can use the showSelectedIcon and selectedIcon fields.
Individual segments can be enabled or disabled with their ButtonSegment.enabled flag. If the onSelectionChanged field is null, then the entire segmented button will be disabled, regardless of the individual segment settings.
This sample shows how to display a SegmentedButton with either a single or multiple selection.
To see it in action, copy and run this code snippet on DartPad.
import 'package:material_ui/material_ui.dart';
/// Flutter code sample for [SegmentedButton].
void main() {
runApp(const SegmentedButtonApp());
}
class SegmentedButtonApp extends StatelessWidget {
const SegmentedButtonApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: .center,
children: <Widget>[
Spacer(),
Text('Single choice'),
SingleChoice(),
SizedBox(height: 20),
Text('Multiple choice'),
MultipleChoice(),
Spacer(),
],
),
),
),
);
}
}
enum Calendar { day, week, month, year }
class SingleChoice extends StatefulWidget {
const SingleChoice({super.key});
@override
State<SingleChoice> createState() => _SingleChoiceState();
}
class _SingleChoiceState extends State<SingleChoice> {
Calendar calendarView = .day;
@override
Widget build(BuildContext context) {
return SegmentedButton<Calendar>(
segments: const <ButtonSegment<Calendar>>[
ButtonSegment<Calendar>(
value: Calendar.day,
label: Text('Day'),
icon: Icon(Icons.calendar_view_day),
),
ButtonSegment<Calendar>(
value: Calendar.week,
label: Text('Week'),
icon: Icon(Icons.calendar_view_week),
),
ButtonSegment<Calendar>(
value: Calendar.month,
label: Text('Month'),
icon: Icon(Icons.calendar_view_month),
),
ButtonSegment<Calendar>(
value: Calendar.year,
label: Text('Year'),
icon: Icon(Icons.calendar_today),
),
],
selected: <Calendar>{calendarView},
onSelectionChanged: (Set<Calendar> newSelection) {
setState(() {
// By default there is only a single segment that can be
// selected at one time, so its value is always the first
// item in the selected set.
calendarView = newSelection.first;
});
},
);
}
}
enum Sizes { extraSmall, small, medium, large, extraLarge }
class MultipleChoice extends StatefulWidget {
const MultipleChoice({super.key});
@override
State<MultipleChoice> createState() => _MultipleChoiceState();
}
class _MultipleChoiceState extends State<MultipleChoice> {
Set<Sizes> selection = <Sizes>{Sizes.large, Sizes.extraLarge};
@override
Widget build(BuildContext context) {
return SegmentedButton<Sizes>(
segments: const <ButtonSegment<Sizes>>[
ButtonSegment<Sizes>(value: Sizes.extraSmall, label: Text('XS')),
ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')),
ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')),
ButtonSegment<Sizes>(value: Sizes.large, label: Text('L')),
ButtonSegment<Sizes>(value: Sizes.extraLarge, label: Text('XL')),
],
selected: selection,
onSelectionChanged: (Set<Sizes> newSelection) {
setState(() {
selection = newSelection;
});
},
multiSelectionEnabled: true,
);
}
}
This sample showcases how to customize SegmentedButton using SegmentedButton.styleFrom.
To see it in action, copy and run this code snippet on DartPad.
import 'package:material_ui/material_ui.dart';
/// Flutter code sample for [SegmentedButton.styleFrom].
void main() {
runApp(const SegmentedButtonApp());
}
class SegmentedButtonApp extends StatelessWidget {
const SegmentedButtonApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(body: Center(child: SegmentedButtonExample())),
);
}
}
class SegmentedButtonExample extends StatefulWidget {
const SegmentedButtonExample({super.key});
@override
State<SegmentedButtonExample> createState() => _SegmentedButtonExampleState();
}
enum Calendar { day, week, month, year }
class _SegmentedButtonExampleState extends State<SegmentedButtonExample> {
Calendar calendarView = .week;
@override
Widget build(BuildContext context) {
return SegmentedButton<Calendar>(
style: SegmentedButton.styleFrom(
backgroundColor: Colors.grey[200],
foregroundColor: Colors.red,
selectedForegroundColor: Colors.white,
selectedBackgroundColor: Colors.green,
),
segments: const <ButtonSegment<Calendar>>[
ButtonSegment<Calendar>(
value: Calendar.day,
label: Text('Day'),
icon: Icon(Icons.calendar_view_day),
),
ButtonSegment<Calendar>(
value: Calendar.week,
label: Text('Week'),
icon: Icon(Icons.calendar_view_week),
),
ButtonSegment<Calendar>(
value: Calendar.month,
label: Text('Month'),
icon: Icon(Icons.calendar_view_month),
),
ButtonSegment<Calendar>(
value: Calendar.year,
label: Text('Year'),
icon: Icon(Icons.calendar_today),
),
],
selected: <Calendar>{calendarView},
onSelectionChanged: (Set<Calendar> newSelection) {
setState(() {
// By default there is only a single segment that can be
// selected at one time, so its value is always the first
// item in the selected set.
calendarView = newSelection.first;
});
},
);
}
}
See also:
- Material Design spec: m3.material.io/components/segmented-buttons/overview
- ButtonStyle, which can be used in the style field to configure the appearance of the button and its segments.
- ToggleButtons, a similar widget that was built for Material 2. SegmentedButton should be considered as a replacement for ToggleButtons.
- Radio, an alternative way to present the user with a mutually exclusive set of options.
- FilterChip, ChoiceChip, which can be used when you need to show more than five options.
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- SegmentedButton
Constructors
-
SegmentedButton({Key? key, required List<
ButtonSegment< segments, required Set<T> >T> selected, void onSelectionChanged(Set<T> )?, bool multiSelectionEnabled = false, bool emptySelectionAllowed = false, EdgeInsets? expandedInsets, ButtonStyle? style, bool showSelectedIcon = true, Widget? selectedIcon, Axis direction = Axis.horizontal}) -
Creates a const SegmentedButton.
const
Properties
- direction → Axis
-
The orientation of the button's segments.
final
- emptySelectionAllowed → bool
-
Determines if having no selected segments is allowed.
final
- expandedInsets → EdgeInsets?
-
Determines the segmented button's size and padding based on expandedInsets.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- multiSelectionEnabled → bool
-
Determines if multiple segments can be selected at one time.
final
-
onSelectionChanged
→ void Function(Set<
T> )? -
The function that is called when the selection changes.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
segments
→ List<
ButtonSegment< T> > -
Descriptions of the segments in the button.
final
-
selected
→ Set<
T> -
The set of ButtonSegment.values that indicate which segments are
selected.
final
- selectedIcon → Widget?
-
An icon that is used to indicate a segment is selected.
final
- showSelectedIcon → bool
-
Determines if the selectedIcon (usually an icon using Icons.check)
is displayed on the selected segments.
final
- style → ButtonStyle?
-
Customizes this button's appearance.
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< SegmentedButton< T> > -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Methods
-
styleFrom(
{Color? foregroundColor, Color? backgroundColor, Color? selectedForegroundColor, Color? selectedBackgroundColor, Color? disabledForegroundColor, Color? disabledBackgroundColor, Color? shadowColor, Color? surfaceTintColor, Color? iconColor, double? iconSize, Color? disabledIconColor, Color? overlayColor, double? elevation, TextStyle? textStyle, EdgeInsetsGeometry? padding, Size? minimumSize, Size? fixedSize, Size? maximumSize, BorderSide? side, OutlinedBorder? shape, MouseCursor? enabledMouseCursor, MouseCursor? disabledMouseCursor, VisualDensity? visualDensity, MaterialTapTargetSize? tapTargetSize, Duration? animationDuration, bool? enableFeedback, AlignmentGeometry? alignment, InteractiveInkFeatureFactory? splashFactory}) → ButtonStyle - A static convenience method that constructs a segmented button ButtonStyle given simple values.