@@ -620,9 +620,15 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
620
620
// During a drag we may have modified the curve, reset it if its possible
621
621
// to do without visual discontinuation.
622
622
if (position.value == 0.0 || position.value == 1.0 ) {
623
- position
624
- ..curve = Curves .easeIn
625
- ..reverseCurve = Curves .easeOut;
623
+ if (Theme .of (context).useMaterial3) {
624
+ position
625
+ ..curve = Curves .easeOutBack
626
+ ..reverseCurve = Curves .easeOutBack.flipped;
627
+ } else {
628
+ position
629
+ ..curve = Curves .easeIn
630
+ ..reverseCurve = Curves .easeOut;
631
+ }
626
632
}
627
633
animateToValue ();
628
634
}
@@ -693,7 +699,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
693
699
694
700
void _handleDragEnd (DragEndDetails details) {
695
701
if (position.value >= 0.5 != widget.value) {
696
- widget.onChanged ! (! widget.value);
702
+ widget.onChanged? . call (! widget.value);
697
703
// Wait with finishing the animation until widget.value has changed to
698
704
// !widget.value as part of the widget.onChanged call above.
699
705
setState (() {
@@ -709,7 +715,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
709
715
void _handleChanged (bool ? value) {
710
716
assert (value != null );
711
717
assert (widget.onChanged != null );
712
- widget.onChanged ! (value! );
718
+ widget.onChanged? . call (value! );
713
719
}
714
720
715
721
@override
@@ -727,11 +733,6 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
727
733
final SwitchThemeData defaults = theme.useMaterial3 ? _SwitchDefaultsM3 (context) : _SwitchDefaultsM2 (context);
728
734
729
735
positionController.duration = Duration (milliseconds: switchConfig.toggleDuration);
730
- if (theme.useMaterial3) {
731
- position
732
- ..curve = Curves .easeOutBack
733
- ..reverseCurve = Curves .easeOutBack.flipped;
734
- }
735
736
736
737
// Colors need to be resolved in selected and non selected states separately
737
738
// so that they can be lerped between.
@@ -780,12 +781,20 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
780
781
?? defaults.overlayColor! .resolve (hoveredStates)! ;
781
782
782
783
final Set <MaterialState > activePressedStates = activeStates..add (MaterialState .pressed);
784
+ final Color effectiveActivePressedThumbColor = widget.thumbColor? .resolve (activePressedStates)
785
+ ?? _widgetThumbColor.resolve (activePressedStates)
786
+ ?? switchTheme.thumbColor? .resolve (activePressedStates)
787
+ ?? defaults.thumbColor! .resolve (activePressedStates)! ;
783
788
final Color effectiveActivePressedOverlayColor = widget.overlayColor? .resolve (activePressedStates)
784
789
?? switchTheme.overlayColor? .resolve (activePressedStates)
785
790
?? activeThumbColor? .withAlpha (kRadialReactionAlpha)
786
791
?? defaults.overlayColor! .resolve (activePressedStates)! ;
787
792
788
793
final Set <MaterialState > inactivePressedStates = inactiveStates..add (MaterialState .pressed);
794
+ final Color effectiveInactivePressedThumbColor = widget.thumbColor? .resolve (inactivePressedStates)
795
+ ?? _widgetThumbColor.resolve (inactivePressedStates)
796
+ ?? switchTheme.thumbColor? .resolve (inactivePressedStates)
797
+ ?? defaults.thumbColor! .resolve (inactivePressedStates)! ;
789
798
final Color effectiveInactivePressedOverlayColor = widget.overlayColor? .resolve (inactivePressedStates)
790
799
?? switchTheme.overlayColor? .resolve (inactivePressedStates)
791
800
?? inactiveThumbColor? .withAlpha (kRadialReactionAlpha)
@@ -830,6 +839,8 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
830
839
..isHovered = states.contains (MaterialState .hovered)
831
840
..activeColor = effectiveActiveThumbColor
832
841
..inactiveColor = effectiveInactiveThumbColor
842
+ ..activePressedColor = effectiveActivePressedThumbColor
843
+ ..inactivePressedColor = effectiveInactivePressedThumbColor
833
844
..activeThumbImage = widget.activeThumbImage
834
845
..onActiveThumbImageError = widget.onActiveThumbImageError
835
846
..inactiveThumbImage = widget.inactiveThumbImage
@@ -926,6 +937,28 @@ class _SwitchPainter extends ToggleablePainter {
926
937
notifyListeners ();
927
938
}
928
939
940
+ Color get activePressedColor => _activePressedColor! ;
941
+ Color ? _activePressedColor;
942
+ set activePressedColor (Color ? value) {
943
+ assert (value != null );
944
+ if (value == _activePressedColor) {
945
+ return ;
946
+ }
947
+ _activePressedColor = value;
948
+ notifyListeners ();
949
+ }
950
+
951
+ Color get inactivePressedColor => _inactivePressedColor! ;
952
+ Color ? _inactivePressedColor;
953
+ set inactivePressedColor (Color ? value) {
954
+ assert (value != null );
955
+ if (value == _inactivePressedColor) {
956
+ return ;
957
+ }
958
+ _inactivePressedColor = value;
959
+ notifyListeners ();
960
+ }
961
+
929
962
double get activeThumbRadius => _activeThumbRadius! ;
930
963
double ? _activeThumbRadius;
931
964
set activeThumbRadius (double value) {
@@ -1180,7 +1213,7 @@ class _SwitchPainter extends ToggleablePainter {
1180
1213
visualPosition = currentValue;
1181
1214
break ;
1182
1215
}
1183
- if (reaction.status == AnimationStatus .reverse && _stopPressAnimation == false ) {
1216
+ if (reaction.status == AnimationStatus .reverse && ! _stopPressAnimation) {
1184
1217
_stopPressAnimation = true ;
1185
1218
} else {
1186
1219
_stopPressAnimation = false ;
@@ -1189,7 +1222,7 @@ class _SwitchPainter extends ToggleablePainter {
1189
1222
// To get the thumb radius when the press ends, the value can be any number
1190
1223
// between activeThumbRadius/inactiveThumbRadius and pressedThumbRadius.
1191
1224
if (! _stopPressAnimation) {
1192
- if (reaction.status == AnimationStatus .completed ) {
1225
+ if (reaction.isCompleted ) {
1193
1226
// This happens when the thumb is dragged instead of being tapped.
1194
1227
_pressedInactiveThumbRadius = lerpDouble (inactiveThumbRadius, pressedThumbRadius, reaction.value);
1195
1228
_pressedActiveThumbRadius = lerpDouble (activeThumbRadius, pressedThumbRadius, reaction.value);
@@ -1248,10 +1281,10 @@ class _SwitchPainter extends ToggleablePainter {
1248
1281
}
1249
1282
1250
1283
Size thumbSize;
1251
- if (reaction.status == AnimationStatus .completed ) {
1284
+ if (reaction.isCompleted ) {
1252
1285
thumbSize = Size .fromRadius (pressedThumbRadius);
1253
1286
} else {
1254
- if (position.status == AnimationStatus .dismissed || position.status == AnimationStatus .forward) {
1287
+ if (position.isDismissed || position.status == AnimationStatus .forward) {
1255
1288
thumbSize = thumbSizeAnimation (true ).value;
1256
1289
} else {
1257
1290
thumbSize = thumbSizeAnimation (false ).value;
@@ -1262,10 +1295,21 @@ class _SwitchPainter extends ToggleablePainter {
1262
1295
final double inset = thumbOffset == null ? 0 : 1.0 - (currentValue - thumbOffset! ).abs () * 2.0 ;
1263
1296
thumbSize = Size (thumbSize.width - inset, thumbSize.height - inset);
1264
1297
1265
- final Color trackColor = Color .lerp (inactiveTrackColor, activeTrackColor, currentValue)! ;
1298
+ final double colorValue = CurvedAnimation (parent: positionController, curve: Curves .easeOut, reverseCurve: Curves .easeIn).value;
1299
+ final Color trackColor = Color .lerp (inactiveTrackColor, activeTrackColor, colorValue)! ;
1266
1300
final Color ? trackOutlineColor = inactiveTrackOutlineColor == null ? null
1267
- : Color .lerp (inactiveTrackOutlineColor, Colors .transparent, currentValue);
1268
- final Color lerpedThumbColor = Color .lerp (inactiveColor, activeColor, currentValue)! ;
1301
+ : Color .lerp (inactiveTrackOutlineColor, Colors .transparent, colorValue);
1302
+ Color lerpedThumbColor;
1303
+ if (! reaction.isDismissed) {
1304
+ lerpedThumbColor = Color .lerp (inactivePressedColor, activePressedColor, colorValue)! ;
1305
+ } else if (positionController.status == AnimationStatus .forward) {
1306
+ lerpedThumbColor = Color .lerp (inactivePressedColor, activeColor, colorValue)! ;
1307
+ } else if (positionController.status == AnimationStatus .reverse) {
1308
+ lerpedThumbColor = Color .lerp (inactiveColor, activePressedColor, colorValue)! ;
1309
+ } else {
1310
+ lerpedThumbColor = Color .lerp (inactiveColor, activeColor, colorValue)! ;
1311
+ }
1312
+
1269
1313
// Blend the thumb color against a `surfaceColor` background in case the
1270
1314
// thumbColor is not opaque. This way we do not see through the thumb to the
1271
1315
// track underneath.
@@ -1289,7 +1333,7 @@ class _SwitchPainter extends ToggleablePainter {
1289
1333
_paintThumbWith (
1290
1334
thumbPaintOffset,
1291
1335
canvas,
1292
- currentValue ,
1336
+ colorValue ,
1293
1337
thumbColor,
1294
1338
thumbImage,
1295
1339
thumbErrorListener,
@@ -1381,7 +1425,7 @@ class _SwitchPainter extends ToggleablePainter {
1381
1425
1382
1426
thumbPainter.paint (
1383
1427
canvas,
1384
- thumbPaintOffset + Offset ( 0 , inset) ,
1428
+ thumbPaintOffset,
1385
1429
configuration.copyWith (size: thumbSize),
1386
1430
);
1387
1431
0 commit comments