@@ -620,9 +620,15 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
620620 // During a drag we may have modified the curve, reset it if its possible
621621 // to do without visual discontinuation.
622622 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+ }
626632 }
627633 animateToValue ();
628634 }
@@ -693,7 +699,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
693699
694700 void _handleDragEnd (DragEndDetails details) {
695701 if (position.value >= 0.5 != widget.value) {
696- widget.onChanged ! (! widget.value);
702+ widget.onChanged? . call (! widget.value);
697703 // Wait with finishing the animation until widget.value has changed to
698704 // !widget.value as part of the widget.onChanged call above.
699705 setState (() {
@@ -709,7 +715,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
709715 void _handleChanged (bool ? value) {
710716 assert (value != null );
711717 assert (widget.onChanged != null );
712- widget.onChanged ! (value! );
718+ widget.onChanged? . call (value! );
713719 }
714720
715721 @override
@@ -727,11 +733,6 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
727733 final SwitchThemeData defaults = theme.useMaterial3 ? _SwitchDefaultsM3 (context) : _SwitchDefaultsM2 (context);
728734
729735 positionController.duration = Duration (milliseconds: switchConfig.toggleDuration);
730- if (theme.useMaterial3) {
731- position
732- ..curve = Curves .easeOutBack
733- ..reverseCurve = Curves .easeOutBack.flipped;
734- }
735736
736737 // Colors need to be resolved in selected and non selected states separately
737738 // so that they can be lerped between.
@@ -780,12 +781,20 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
780781 ?? defaults.overlayColor! .resolve (hoveredStates)! ;
781782
782783 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)! ;
783788 final Color effectiveActivePressedOverlayColor = widget.overlayColor? .resolve (activePressedStates)
784789 ?? switchTheme.overlayColor? .resolve (activePressedStates)
785790 ?? activeThumbColor? .withAlpha (kRadialReactionAlpha)
786791 ?? defaults.overlayColor! .resolve (activePressedStates)! ;
787792
788793 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)! ;
789798 final Color effectiveInactivePressedOverlayColor = widget.overlayColor? .resolve (inactivePressedStates)
790799 ?? switchTheme.overlayColor? .resolve (inactivePressedStates)
791800 ?? inactiveThumbColor? .withAlpha (kRadialReactionAlpha)
@@ -830,6 +839,8 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
830839 ..isHovered = states.contains (MaterialState .hovered)
831840 ..activeColor = effectiveActiveThumbColor
832841 ..inactiveColor = effectiveInactiveThumbColor
842+ ..activePressedColor = effectiveActivePressedThumbColor
843+ ..inactivePressedColor = effectiveInactivePressedThumbColor
833844 ..activeThumbImage = widget.activeThumbImage
834845 ..onActiveThumbImageError = widget.onActiveThumbImageError
835846 ..inactiveThumbImage = widget.inactiveThumbImage
@@ -926,6 +937,28 @@ class _SwitchPainter extends ToggleablePainter {
926937 notifyListeners ();
927938 }
928939
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+
929962 double get activeThumbRadius => _activeThumbRadius! ;
930963 double ? _activeThumbRadius;
931964 set activeThumbRadius (double value) {
@@ -1180,7 +1213,7 @@ class _SwitchPainter extends ToggleablePainter {
11801213 visualPosition = currentValue;
11811214 break ;
11821215 }
1183- if (reaction.status == AnimationStatus .reverse && _stopPressAnimation == false ) {
1216+ if (reaction.status == AnimationStatus .reverse && ! _stopPressAnimation) {
11841217 _stopPressAnimation = true ;
11851218 } else {
11861219 _stopPressAnimation = false ;
@@ -1189,7 +1222,7 @@ class _SwitchPainter extends ToggleablePainter {
11891222 // To get the thumb radius when the press ends, the value can be any number
11901223 // between activeThumbRadius/inactiveThumbRadius and pressedThumbRadius.
11911224 if (! _stopPressAnimation) {
1192- if (reaction.status == AnimationStatus .completed ) {
1225+ if (reaction.isCompleted ) {
11931226 // This happens when the thumb is dragged instead of being tapped.
11941227 _pressedInactiveThumbRadius = lerpDouble (inactiveThumbRadius, pressedThumbRadius, reaction.value);
11951228 _pressedActiveThumbRadius = lerpDouble (activeThumbRadius, pressedThumbRadius, reaction.value);
@@ -1248,10 +1281,10 @@ class _SwitchPainter extends ToggleablePainter {
12481281 }
12491282
12501283 Size thumbSize;
1251- if (reaction.status == AnimationStatus .completed ) {
1284+ if (reaction.isCompleted ) {
12521285 thumbSize = Size .fromRadius (pressedThumbRadius);
12531286 } else {
1254- if (position.status == AnimationStatus .dismissed || position.status == AnimationStatus .forward) {
1287+ if (position.isDismissed || position.status == AnimationStatus .forward) {
12551288 thumbSize = thumbSizeAnimation (true ).value;
12561289 } else {
12571290 thumbSize = thumbSizeAnimation (false ).value;
@@ -1262,10 +1295,21 @@ class _SwitchPainter extends ToggleablePainter {
12621295 final double inset = thumbOffset == null ? 0 : 1.0 - (currentValue - thumbOffset! ).abs () * 2.0 ;
12631296 thumbSize = Size (thumbSize.width - inset, thumbSize.height - inset);
12641297
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)! ;
12661300 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+
12691313 // Blend the thumb color against a `surfaceColor` background in case the
12701314 // thumbColor is not opaque. This way we do not see through the thumb to the
12711315 // track underneath.
@@ -1289,7 +1333,7 @@ class _SwitchPainter extends ToggleablePainter {
12891333 _paintThumbWith (
12901334 thumbPaintOffset,
12911335 canvas,
1292- currentValue ,
1336+ colorValue ,
12931337 thumbColor,
12941338 thumbImage,
12951339 thumbErrorListener,
@@ -1381,7 +1425,7 @@ class _SwitchPainter extends ToggleablePainter {
13811425
13821426 thumbPainter.paint (
13831427 canvas,
1384- thumbPaintOffset + Offset ( 0 , inset) ,
1428+ thumbPaintOffset,
13851429 configuration.copyWith (size: thumbSize),
13861430 );
13871431
0 commit comments