@@ -18,6 +18,9 @@ const EdgeInsetsGeometry _kHorizontalItemPadding = EdgeInsets.symmetric(horizont
1818// Minimum height of the segmented control.
1919const double _kMinSegmentedControlHeight = 28.0 ;
2020
21+ // The default color used for the text of the disabled segment.
22+ const Color _kDisableTextColor = Color .fromARGB (115 , 122 , 122 , 122 );
23+
2124// The duration of the fade animation used to transition when a new widget
2225// is selected.
2326const Duration _kFadeDuration = Duration (milliseconds: 165 );
@@ -57,17 +60,26 @@ const Duration _kFadeDuration = Duration(milliseconds: 165);
5760/// A segmented control may optionally be created with custom colors. The
5861/// [unselectedColor] , [selectedColor] , [borderColor] , and [pressedColor]
5962/// arguments can be used to override the segmented control's colors from
60- /// [CupertinoTheme] defaults.
63+ /// [CupertinoTheme] defaults. The [disabledColor] and [disabledTextColor]
64+ /// set the background and text colors of the segment when it is disabled.
65+ ///
66+ /// The segmented control can be disabled by adding children to the [Set] of
67+ /// [disabledChildren] . If the child is not present in the [Set] , it is enabled
68+ /// by default.
6169///
6270/// {@tool dartpad}
6371/// This example shows a [CupertinoSegmentedControl] with an enum type.
6472///
6573/// The callback provided to [onValueChanged] should update the state of
6674/// the parent [StatefulWidget] using the [State.setState] method, so that
67- /// the parent gets rebuilt; for example:
75+ /// the parent gets rebuilt.
76+ ///
77+ /// This example also demonstrates how to use the [disabledChildren] property by
78+ /// toggling each [Switch] to enable or disable the segments.
6879///
6980/// ** See code in examples/api/lib/cupertino/segmented_control/cupertino_segmented_control.0.dart **
7081/// {@end-tool}
82+ ///
7183/// See also:
7284///
7385/// * [CupertinoSegmentedControl] , a segmented control widget in the style used
@@ -98,7 +110,10 @@ class CupertinoSegmentedControl<T extends Object> extends StatefulWidget {
98110 this .selectedColor,
99111 this .borderColor,
100112 this .pressedColor,
113+ this .disabledColor,
114+ this .disabledTextColor,
101115 this .padding,
116+ this .disabledChildren = const < Never > {},
102117 }) : assert (children.length >= 2 ),
103118 assert (
104119 groupValue == null || children.keys.any ((T child) => child == groupValue),
@@ -148,11 +163,26 @@ class CupertinoSegmentedControl<T extends Object> extends StatefulWidget {
148163 /// Defaults to the selectedColor at 20% opacity if null.
149164 final Color ? pressedColor;
150165
166+ /// The color used to fill the background of the segment when it is disabled.
167+ ///
168+ /// If null, this color will be 50% opacity of the [selectedColor] when
169+ /// the segment is selected. If the segment is unselected, this color will be
170+ /// set to [unselectedColor] .
171+ final Color ? disabledColor;
172+
173+ /// The color used for the text of the segment when it is disabled.
174+ final Color ? disabledTextColor;
175+
151176 /// The CupertinoSegmentedControl will be placed inside this padding.
152177 ///
153178 /// Defaults to EdgeInsets.symmetric(horizontal: 16.0)
154179 final EdgeInsetsGeometry ? padding;
155180
181+ /// The set of identifying keys that correspond to the segments that should be disabled.
182+ ///
183+ /// All segments are enabled by default.
184+ final Set <T > disabledChildren;
185+
156186 @override
157187 State <CupertinoSegmentedControl <T >> createState () => _SegmentedControlState <T >();
158188}
@@ -172,6 +202,9 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
172202 Color ? _unselectedColor;
173203 Color ? _borderColor;
174204 Color ? _pressedColor;
205+ Color ? _selectedDisabledColor;
206+ Color ? _unselectedDisabledColor;
207+ Color ? _disabledTextColor;
175208
176209 AnimationController createAnimationController () {
177210 return AnimationController (
@@ -187,6 +220,11 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
187220 bool _updateColors () {
188221 assert (mounted, 'This should only be called after didUpdateDependencies' );
189222 bool changed = false ;
223+ final Color disabledTextColor = widget.disabledTextColor ?? _kDisableTextColor;
224+ if (_disabledTextColor != disabledTextColor) {
225+ changed = true ;
226+ _disabledTextColor = disabledTextColor;
227+ }
190228 final Color selectedColor = widget.selectedColor ?? CupertinoTheme .of (context).primaryColor;
191229 if (_selectedColor != selectedColor) {
192230 changed = true ;
@@ -197,6 +235,13 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
197235 changed = true ;
198236 _unselectedColor = unselectedColor;
199237 }
238+ final Color selectedDisabledColor = widget.disabledColor ?? selectedColor.withOpacity (0.5 );
239+ final Color unselectedDisabledColor = widget.disabledColor ?? unselectedColor;
240+ if (_selectedDisabledColor != selectedDisabledColor || _unselectedDisabledColor != unselectedDisabledColor) {
241+ changed = true ;
242+ _selectedDisabledColor = selectedDisabledColor;
243+ _unselectedDisabledColor = unselectedDisabledColor;
244+ }
200245 final Color borderColor = widget.borderColor ?? CupertinoTheme .of (context).primaryColor;
201246 if (_borderColor != borderColor) {
202247 changed = true ;
@@ -302,13 +347,18 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
302347 if (currentKey != _pressedKey) {
303348 return ;
304349 }
305- if (currentKey != widget.groupValue) {
306- widget.onValueChanged (currentKey);
350+ if (! widget.disabledChildren.contains (currentKey)) {
351+ if (currentKey != widget.groupValue) {
352+ widget.onValueChanged (currentKey);
353+ }
307354 }
308355 _pressedKey = null ;
309356 }
310357
311358 Color ? getTextColor (int index, T currentKey) {
359+ if (widget.disabledChildren.contains (currentKey)) {
360+ return _disabledTextColor;
361+ }
312362 if (_selectionControllers[index].isAnimating) {
313363 return _textColorTween.evaluate (_selectionControllers[index]);
314364 }
@@ -319,6 +369,9 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
319369 }
320370
321371 Color ? getBackgroundColor (int index, T currentKey) {
372+ if (widget.disabledChildren.contains (currentKey)) {
373+ return widget.groupValue == currentKey ? _selectedDisabledColor : _unselectedDisabledColor;
374+ }
322375 if (_selectionControllers[index].isAnimating) {
323376 return _childTweens[index].evaluate (_selectionControllers[index]);
324377 }
@@ -357,10 +410,10 @@ class _SegmentedControlState<T extends Object> extends State<CupertinoSegmentedC
357410 cursor: kIsWeb ? SystemMouseCursors .click : MouseCursor .defer,
358411 child: GestureDetector (
359412 behavior: HitTestBehavior .opaque,
360- onTapDown: (TapDownDetails event) {
413+ onTapDown: widget.disabledChildren. contains (currentKey) ? null : (TapDownDetails event) {
361414 _onTapDown (currentKey);
362415 },
363- onTapCancel: _onTapCancel,
416+ onTapCancel: widget.disabledChildren. contains (currentKey) ? null : _onTapCancel,
364417 onTap: () {
365418 _onTap (currentKey);
366419 },
0 commit comments