Repository: splashbyte/animated_toggle_switch

Issue:
Theme switching occurs with a delay

https://github.com/splashbyte/animated_toggle_switch/assets/18004353/6e068863-d350-4bad-b30a-bd2e4777d092

When changing the theme, rebuilding will not cause the colors to change immediately



Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf4c0b0..fc33dcc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
 
 - adds `indicatorGradient` to `ToggleStyle` ([#44](https://github.com/splashbyte/animated_toggle_switch/issues/44))
 - fixes problems with `backgroundGradient` and `backgroundColor` ([#46](https://github.com/splashbyte/animated_toggle_switch/issues/46))
+- adds `AnimationType.none`
+- introduces `CustomToggleStyle` for disabling the animation of single style properties
 
 ## 0.8.0 (2023-09-02)
 
diff --git a/example/lib/load_switch.dart b/example/lib/load_switch.dart
new file mode 100644
index 0000000..d0b6748
--- /dev/null
+++ b/example/lib/load_switch.dart
@@ -0,0 +1,64 @@
+// This switch is inspired by https://pub.dev/packages/load_switch
+
+import 'package:animated_toggle_switch/animated_toggle_switch.dart';
+import 'package:flutter/material.dart';
+
+class LoadSwitch extends StatefulWidget {
+  const LoadSwitch({super.key});
+
+  @override
+  State<LoadSwitch> createState() => _LoadSwitchState();
+}
+
+class _LoadSwitchState extends State<LoadSwitch> {
+  bool value = false;
+
+  @override
+  Widget build(BuildContext context) {
+    const height = 50.0;
+    const borderWidth = 5.0;
+    return CustomAnimatedToggleSwitch(
+      height: height,
+      indicatorSize: Size.square(height),
+      current: value,
+      values: [false, true],
+      onChanged: (newValue) {
+        setState(() => value = newValue);
+        return Future.delayed(const Duration(seconds: 2));
+      },
+      animationDuration: const Duration(milliseconds: 350),
+      iconArrangement: IconArrangement.overlap,
+      spacing: -16.0,
+      wrapperBuilder: (context, global, child) => DecoratedBox(
+          decoration: BoxDecoration(
+              color: Color.lerp(
+                  Color.lerp(Colors.red, Colors.green, global.position),
+                  Colors.grey,
+                  global.loadingAnimationValue),
+              borderRadius:
+                  const BorderRadius.all(Radius.circular(height / 2))),
+          child: child),
+      foregroundIndicatorBuilder: (context, global) {
+        return Stack(
+          fit: StackFit.expand,
+          children: [
+            Padding(
+              padding: const EdgeInsets.all(borderWidth),
+              child: DecoratedBox(
+                  decoration: BoxDecoration(
+                      shape: BoxShape.circle, color: Colors.white)),
+            ),
+            Padding(
+              padding: const EdgeInsets.all(borderWidth / 2),
+              child: CircularProgressIndicator(
+                strokeWidth: borderWidth,
+                color: Colors.blue.withOpacity(global.loadingAnimationValue),
+              ),
+            ),
+          ],
+        );
+      },
+      iconBuilder: (context, local, global) => const SizedBox(),
+    );
+  }
+}
diff --git a/example/lib/main.dart b/example/lib/main.dart
index ef17b07..1dc36e7 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -2,6 +2,7 @@ import 'dart:math';
 
 import 'package:animated_toggle_switch/animated_toggle_switch.dart';
 import 'package:example/crazy_switch.dart';
+import 'package:example/load_switch.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
@@ -395,6 +396,23 @@ class _MyHomePageState extends State<MyHomePage> {
                 padding: const EdgeInsets.only(top: 8.0, bottom: 16.0),
                 child: const CrazySwitch(),
               ),
+              Padding(
+                padding: const EdgeInsets.all(8.0),
+                child: Text.rich(
+                  TextSpan(children: [
+                    TextSpan(text: 'Switch inspired by '),
+                    TextSpan(
+                        text: 'load_switch',
+                        style: tappableTextStyle,
+                        recognizer: TapGestureRecognizer()
+                          ..onTap = () => launchUrl(loadSwitchUrl))
+                  ]),
+                ),
+              ),
+              Padding(
+                padding: const EdgeInsets.only(top: 8.0, bottom: 16.0),
+                child: const LoadSwitch(),
+              ),
               Padding(
                 padding: const EdgeInsets.all(8.0),
                 child: Text(
@@ -855,3 +873,4 @@ final liteRollingSwitchUrl =
     Uri.parse('https://pub.dev/packages/lite_rolling_switch');
 final crazySwitchUrl =
     Uri.parse('https://github.com/pedromassango/crazy-switch');
+final loadSwitchUrl = Uri.parse('https://pub.dev/packages/load_switch');
diff --git a/lib/animated_toggle_switch.dart b/lib/animated_toggle_switch.dart
index fe0c859..69be9a9 100644
--- a/lib/animated_toggle_switch.dart
+++ b/lib/animated_toggle_switch.dart
@@ -3,6 +3,7 @@ library animated_toggle_switch;
 import 'dart:async';
 import 'dart:math';
 
+import 'package:animated_toggle_switch/src/test_keys.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/gestures.dart';
diff --git a/lib/src/style.dart b/lib/src/style.dart
index 1424885..a67e2b9 100644
--- a/lib/src/style.dart
+++ b/lib/src/style.dart
@@ -1,6 +1,194 @@
 part of 'package:animated_toggle_switch/animated_toggle_switch.dart';
 
-class ToggleStyle {
+/// The base class for all toggle styles.
+abstract class _BaseToggleStyle {
+  const _BaseToggleStyle._();
+
+  ToggleStyleProperty<Color>? get _indicatorColor;
+
+  ToggleStyleProperty<Gradient>? get _indicatorGradient;
+
+  ToggleStyleProperty<Color>? get _backgroundColor;
+
+  ToggleStyleProperty<Gradient>? get _backgroundGradient;
+
+  ToggleStyleProperty<Color>? get _borderColor;
+
+  ToggleStyleProperty<BorderRadiusGeometry>? get _borderRadius;
+
+  ToggleStyleProperty<BorderRadiusGeometry>? get _indicatorBorderRadius;
+
+  ToggleStyleProperty<BoxBorder>? get _indicatorBorder;
+
+  ToggleStyleProperty<List<BoxShadow>>? get _indicatorBoxShadow;
+
+  ToggleStyleProperty<List<BoxShadow>>? get _boxShadow;
+
+  _BaseToggleStyle _merge(
+    _BaseToggleStyle? other,
+    BorderRadiusGeometry indicatorBorderRadiusDifference,
+  ) =>
+      other == null
+          ? this
+          : _CustomToggleStyle._(
+              indicatorColor: other._indicatorColor ?? _indicatorColor,
+              indicatorGradient: other._indicatorGradient ??
+                  (other._indicatorColor != null ? null : _indicatorGradient),
+              backgroundColor: other._backgroundColor ?? _backgroundColor,
+              backgroundGradient: other._backgroundGradient ??
+                  (other._backgroundColor != null ? null : _backgroundGradient),
+              borderColor: other._borderColor ?? _borderColor,
+              borderRadius: other._borderRadius ?? _borderRadius,
+              indicatorBorderRadius: other._indicatorBorderRadius ??
+                  other._borderRadius?._map((value) =>
+                      value.subtract(indicatorBorderRadiusDifference)) ??
+                  _indicatorBorderRadius ??
+                  _borderRadius?._map((value) =>
+                      value.subtract(indicatorBorderRadiusDifference)),
+              indicatorBorder: other._indicatorBorder ?? _indicatorBorder,
+              indicatorBoxShadow:
+                  other._indicatorBoxShadow ?? _indicatorBoxShadow,
+              boxShadow: other._boxShadow ?? _boxShadow,
+            );
+
+  static _BaseToggleStyle Function(
+      _BaseToggleStyle style1, _BaseToggleStyle style2, double t) _lerpFunction(
+          AnimationType animationType) =>
+      (style1, style2, t) => _lerp(style1, style2, t, animationType);
+
+  static _BaseToggleStyle _lerp(_BaseToggleStyle style1,
+          _BaseToggleStyle style2, double t, AnimationType animationType) =>
+      _CustomToggleStyle._(
+        indicatorColor: ToggleStyleProperty._lerpConditional(
+            style1._indicatorColor,
+            style2._indicatorColor,
+            t,
+            Color.lerp,
+            animationType),
+        indicatorGradient: ToggleStyleProperty._lerpConditional(
+            style1._indicatorGradient ??
+                style1._indicatorColor?._map((value) => value.toGradient()),
+            style2._indicatorGradient ??
+                style2._indicatorColor?._map((value) => value.toGradient()),
+            t,
+            Gradient.lerp,
+            animationType),
+        backgroundColor: ToggleStyleProperty._lerpConditional(
+            style1._backgroundColor,
+            style2._backgroundColor,
+            t,
+            Color.lerp,
+            animationType),
+        backgroundGradient: ToggleStyleProperty._lerpConditional(
+            style1._backgroundGradient ??
+                style1._backgroundColor?._map((value) => value.toGradient()),
+            style2._backgroundGradient ??
+                style2._backgroundColor?._map((value) => value.toGradient()),
+            t,
+            Gradient.lerp,
+            animationType),
+        borderColor: ToggleStyleProperty._lerpConditional(style1._borderColor,
+            style2._borderColor, t, Color.lerp, animationType),
+        borderRadius: ToggleStyleProperty._lerpConditional(style1._borderRadius,
+            style2._borderRadius, t, BorderRadiusGeometry.lerp, animationType),
+        indicatorBorderRadius: ToggleStyleProperty._lerpConditional(
+            style1._indicatorBorderRadius ?? style1._borderRadius,
+            style2._indicatorBorderRadius ?? style2._borderRadius,
+            t,
+            BorderRadiusGeometry.lerp,
+            animationType),
+        indicatorBorder: ToggleStyleProperty._lerpConditional(
+            style1._indicatorBorder,
+            style2._indicatorBorder,
+            t,
+            BoxBorder.lerp,
+            animationType),
+        indicatorBoxShadow: ToggleStyleProperty._lerpConditional(
+            style1._indicatorBoxShadow,
+            style2._indicatorBoxShadow,
+            t,
+            BoxShadow.lerpList,
+            animationType),
+        boxShadow: ToggleStyleProperty._lerpConditional(style1._boxShadow,
+            style2._boxShadow, t, BoxShadow.lerpList, animationType),
+      );
+}
+
+/// Currently not supported.
+class _CustomToggleStyle extends _BaseToggleStyle {
+  @override
+  final ToggleStyleProperty<Color>? _indicatorColor;
+  @override
+  final ToggleStyleProperty<Gradient>? _indicatorGradient;
+  @override
+  final ToggleStyleProperty<Color>? _backgroundColor;
+  @override
+  final ToggleStyleProperty<Gradient>? _backgroundGradient;
+  @override
+  final ToggleStyleProperty<Color>? _borderColor;
+  @override
+  final ToggleStyleProperty<BorderRadiusGeometry>? _borderRadius;
+  @override
+  final ToggleStyleProperty<BorderRadiusGeometry>? _indicatorBorderRadius;
+  @override
+  final ToggleStyleProperty<BoxBorder>? _indicatorBorder;
+  @override
+  final ToggleStyleProperty<List<BoxShadow>>? _indicatorBoxShadow;
+  @override
+  final ToggleStyleProperty<List<BoxShadow>>? _boxShadow;
+
+  /// Default constructor for [_CustomToggleStyle].
+  ///
+  /// If you don't want to disable the animation of single properties,
+  /// you should use [ToggleStyle] instead.
+  const _CustomToggleStyle({
+    ToggleStyleProperty<Color>? indicatorColor,
+    ToggleStyleProperty<Gradient>? indicatorGradient,
+    ToggleStyleProperty<Color>? backgroundColor,
+    ToggleStyleProperty<Gradient>? backgroundGradient,
+    ToggleStyleProperty<Color>? borderColor,
+    ToggleStyleProperty<BorderRadiusGeometry>? borderRadius,
+    ToggleStyleProperty<BorderRadiusGeometry>? indicatorBorderRadius,
+    ToggleStyleProperty<BoxBorder>? indicatorBorder,
+    ToggleStyleProperty<List<BoxShadow>>? indicatorBoxShadow,
+    ToggleStyleProperty<List<BoxShadow>>? boxShadow,
+  })  : _indicatorColor = indicatorColor,
+        _indicatorGradient = indicatorGradient,
+        _backgroundColor = backgroundColor,
+        _backgroundGradient = backgroundGradient,
+        _borderColor = borderColor,
+        _borderRadius = borderRadius,
+        _indicatorBorderRadius = indicatorBorderRadius,
+        _indicatorBorder = indicatorBorder,
+        _indicatorBoxShadow = indicatorBoxShadow,
+        _boxShadow = boxShadow,
+        super._();
+
+  const _CustomToggleStyle._({
+    required ToggleStyleProperty<Color>? indicatorColor,
+    required ToggleStyleProperty<Gradient>? indicatorGradient,
+    required ToggleStyleProperty<Color>? backgroundColor,
+    required ToggleStyleProperty<Gradient>? backgroundGradient,
+    required ToggleStyleProperty<Color>? borderColor,
+    required ToggleStyleProperty<BorderRadiusGeometry>? borderRadius,
+    required ToggleStyleProperty<BorderRadiusGeometry>? indicatorBorderRadius,
+    required ToggleStyleProperty<BoxBorder>? indicatorBorder,
+    required ToggleStyleProperty<List<BoxShadow>>? indicatorBoxShadow,
+    required ToggleStyleProperty<List<BoxShadow>>? boxShadow,
+  })  : _indicatorColor = indicatorColor,
+        _indicatorGradient = indicatorGradient,
+        _backgroundColor = backgroundColor,
+        _backgroundGradient = backgroundGradient,
+        _borderColor = borderColor,
+        _borderRadius = borderRadius,
+        _indicatorBorderRadius = indicatorBorderRadius,
+        _indicatorBorder = indicatorBorder,
+        _indicatorBoxShadow = indicatorBoxShadow,
+        _boxShadow = boxShadow,
+        super._();
+}
+
+class ToggleStyle extends _BaseToggleStyle {
   /// Background color of the indicator.
   ///
   /// Defaults to [ThemeData.colorScheme.secondary].
@@ -42,6 +230,9 @@ class ToggleStyle {
   final List<BoxShadow>? boxShadow;
 
   /// Default constructor for [ToggleStyle].
+  ///
+  /// If you want to disable the animation of single properties,
+  /// you can use [_CustomToggleStyle] for this purpose.
   const ToggleStyle({
     this.indicatorColor,
     this.indicatorGradient,
@@ -53,9 +244,8 @@ class ToggleStyle {
     this.indicatorBorder,
     this.indicatorBoxShadow,
     this.boxShadow,
-  });
+  }) : super._();
 
-  /// Private constructor for setting all possible parameters.
   const ToggleStyle._({
     required this.indicatorColor,
     required this.indicatorGradient,
@@ -67,78 +257,47 @@ class ToggleStyle {
     required this.indicatorBorder,
     required this.indicatorBoxShadow,
     required this.boxShadow,
-  });
+  }) : super._();
 
-  ToggleStyle _merge(
-    ToggleStyle? other,
-    BorderRadiusGeometry indicatorBorderRadiusDifference,
-  ) =>
-      other == null
-          ? this
-          : ToggleStyle._(
-              indicatorColor: other.indicatorColor ?? indicatorColor,
-              indicatorGradient: other.indicatorGradient ??
-                  (other.indicatorColor != null ? null : indicatorGradient),
-              backgroundColor: other.backgroundColor ?? backgroundColor,
-              backgroundGradient: other.backgroundGradient ??
-                  (other.backgroundColor != null ? null : backgroundGradient),
-              borderColor: other.borderColor ?? borderColor,
-              borderRadius: other.borderRadius ?? borderRadius,
-              indicatorBorderRadius: other.indicatorBorderRadius ??
-                  other.borderRadius
-                      .subtractNullable(indicatorBorderRadiusDifference) ??
-                  indicatorBorderRadius ??
-                  borderRadius
-                      .subtractNullable(indicatorBorderRadiusDifference),
-              indicatorBorder: other.indicatorBorder ?? indicatorBorder,
-              indicatorBoxShadow:
-                  other.indicatorBoxShadow ?? indicatorBoxShadow,
-              boxShadow: other.boxShadow ?? boxShadow,
-            );
+  @override
+  ToggleStyleProperty<Color>? get _backgroundColor =>
+      ToggleStyleProperty.nullable(backgroundColor);
 
-  static ToggleStyle _lerp(ToggleStyle style1, ToggleStyle style2, double t) =>
-      ToggleStyle._(
-        indicatorColor:
-            Color.lerp(style1.indicatorColor, style2.indicatorColor, t),
-        indicatorGradient: Gradient.lerp(
-          style1.indicatorGradient ?? style1.indicatorColor?.toGradient(),
-          style2.indicatorGradient ?? style2.indicatorColor?.toGradient(),
-          t,
-        ),
-        backgroundColor:
-            Color.lerp(style1.backgroundColor, style2.backgroundColor, t),
-        backgroundGradient: Gradient.lerp(
-          style1.backgroundGradient ?? style1.backgroundColor?.toGradient(),
-          style2.backgroundGradient ?? style2.backgroundColor?.toGradient(),
-          t,
-        ),
-        borderColor: Color.lerp(style1.borderColor, style2.borderColor, t),
-        borderRadius: BorderRadiusGeometry.lerp(
-          style1.borderRadius,
-          style2.borderRadius,
-          t,
-        ),
-        indicatorBorderRadius: BorderRadiusGeometry.lerp(
-          style1.indicatorBorderRadius ?? style1.borderRadius,
-          style2.indicatorBorderRadius ?? style2.borderRadius,
-          t,
-        ),
-        indicatorBorder: BoxBorder.lerp(
-          style1.indicatorBorder,
-          style2.indicatorBorder,
-          t,
-        ),
-        indicatorBoxShadow: BoxShadow.lerpList(
-          style1.indicatorBoxShadow,
-          style2.indicatorBoxShadow,
-          t,
-        ),
-        boxShadow: BoxShadow.lerpList(
-          style1.boxShadow,
-          style2.boxShadow,
-          t,
-        ),
-      );
+  @override
+  ToggleStyleProperty<Gradient>? get _backgroundGradient =>
+      ToggleStyleProperty.nullable(backgroundGradient);
+
+  @override
+  ToggleStyleProperty<Color>? get _borderColor =>
+      ToggleStyleProperty.nullable(borderColor);
+
+  @override
+  ToggleStyleProperty<BorderRadiusGeometry>? get _borderRadius =>
+      ToggleStyleProperty.nullable(borderRadius);
+
+  @override
+  ToggleStyleProperty<List<BoxShadow>>? get _boxShadow =>
+      ToggleStyleProperty.nullable(boxShadow);
+
+  @override
+  ToggleStyleProperty<BoxBorder>? get _indicatorBorder =>
+      ToggleStyleProperty.nullable(indicatorBorder);
+
+  @override
+  ToggleStyleProperty<BorderRadiusGeometry>? get _indicatorBorderRadius =>
+      ToggleStyleProperty.nullable(indicatorBorderRadius);
+
+  @override
+  ToggleStyleProperty<List<BoxShadow>>? get _indicatorBoxShadow =>
+      ToggleStyleProperty.nullable(indicatorBoxShadow);
+
+  @override
+  ToggleStyleProperty<Color>? get _indicatorColor =>
+      ToggleStyleProperty.nullable(indicatorColor);
+
+  @override
+  ToggleStyleProperty<Gradient>? get _indicatorGradient =>
+      ToggleStyleProperty.nullable(indicatorGradient);
 
   // coverage:ignore-start
 
@@ -174,9 +333,45 @@ class ToggleStyle {
 // coverage:ignore-end
 }
 
-extension _XSubtractNullable on BorderRadiusGeometry? {
-  BorderRadiusGeometry? subtractNullable(BorderRadiusGeometry other) {
-    if (this == null) return null;
-    return this!.subtract(other);
+class ToggleStyleProperty<T> {
+  /// The value of this property.
+  final T value;
+
+  /// Indicates if this property will be animated when changed.
+  final bool animationEnabled;
+
+  const ToggleStyleProperty(
+    this.value, {
+    this.animationEnabled = true,
+  });
+
+  static ToggleStyleProperty<T>? nullable<T>(
+    T? value, {
+    bool animationEnabled = true,
+  }) =>
+      value == null
+          ? null
+          : ToggleStyleProperty(value, animationEnabled: animationEnabled);
+
+  ToggleStyleProperty<S> _map<S>(S Function(T value) map) =>
+      ToggleStyleProperty(
+        map(value),
+        animationEnabled: animationEnabled,
+      );
+
+  static ToggleStyleProperty<T>? _lerpConditional<T>(
+      ToggleStyleProperty<T>? prop1,
+      ToggleStyleProperty<T>? prop2,
+      double t,
+      T? Function(T?, T?, double) lerp,
+      AnimationType animationType) {
+    if (prop1?.animationEnabled != true && prop2?.animationEnabled != true) {
+      if (animationType == AnimationType.onHover && t < 0.5) return prop1;
+      return prop2;
+    }
+    return ToggleStyleProperty.nullable(
+      lerp(prop1?.value, prop2?.value, t),
+      animationEnabled: true,
+    );
   }
 }
diff --git a/lib/src/widgets/animated_toggle_switch.dart b/lib/src/widgets/animated_toggle_switch.dart
index fa3dd0b..461258f 100644
--- a/lib/src/widgets/animated_toggle_switch.dart
+++ b/lib/src/widgets/animated_toggle_switch.dart
@@ -13,7 +13,7 @@ typedef SimpleRollingIconBuilder<T> = Widget Function(T value, bool foreground);
 typedef LoadingIconBuilder<T> = Widget Function(
     BuildContext context, DetailedGlobalToggleProperties<T> global);
 
-/// A version of IconBuilder for writing a own Animation on the change of the selected item.
+/// A version of [IconBuilder] for writing a custom animation for the change of the selected item.
 typedef AnimatedIconBuilder<T> = Widget Function(
     BuildContext context,
     AnimatedToggleProperties<T> local,
@@ -37,6 +37,9 @@ typedef SeparatorBuilder = Widget Function(int index);
 
 /// Specifies when an value should be animated.
 enum AnimationType {
+  /// Disables the animation.
+  none,
+
   /// Starts an animation if an item is selected.
   onSelected,
 
@@ -82,7 +85,7 @@ class AnimatedToggleSwitch<T extends Object?>
   /// All possible values.
   final List<T> values;
 
-  /// The IconBuilder for all icons with the specified size.
+  /// The [IconBuilder] for all icons with the specified size.
   final AnimatedIconBuilder<T>? animatedIconBuilder;
 
   /// The default style of this switch.
@@ -272,6 +275,8 @@ class AnimatedToggleSwitch<T extends Object?>
   /// For deactivating this animation please set [inactiveOpacity] to [1.0].
   final Duration inactiveOpacityDuration;
 
+  final bool animateStyleChanges = true;
+
   /// Constructor of AnimatedToggleSwitch with all possible settings.
   ///
   /// Consider using [CustomAnimatedToggleSwitch] for maximum customizability.
@@ -996,7 +1001,7 @@ class AnimatedToggleSwitch<T extends Object?>
           DetailedGlobalToggleProperties<dynamic> properties) =>
       const _MyLoading();
 
-  ToggleStyle? _styleBuilder(BuildContext context,
+  _BaseToggleStyle? _styleBuilder(BuildContext context,
       StyledToggleProperties<T> local, GlobalToggleProperties<T> global) {
     if (customStyleBuilder != null) {
       return customStyleBuilder!(context, local, global);
@@ -1078,34 +1083,35 @@ class AnimatedToggleSwitch<T extends Object?>
             opacity: global.active ? 1.0 : inactiveOpacity,
             duration: inactiveOpacityDuration,
             curve: inactiveOpacityCurve,
-            child: _animationTypeBuilder<ToggleStyle>(
+            child: _animationTypeBuilder<_BaseToggleStyle>(
               context,
               styleAnimationType,
               (local) => style._merge(
                 _styleBuilder(context, local, global),
                 _indicatorBorderRadiusDifference,
               ),
-              ToggleStyle._lerp,
+              _BaseToggleStyle._lerpFunction(styleAnimationType),
               (style) => DecoratedBox(
                 decoration: BoxDecoration(
-                  color: style.backgroundColor,
-                  gradient: style.backgroundGradient,
-                  borderRadius: style.borderRadius,
-                  boxShadow: style.boxShadow,
+                  color: style._backgroundColor?.value,
+                  gradient: style._backgroundGradient?.value,
+                  borderRadius: style._borderRadius?.value,
+                  boxShadow: style._boxShadow?.value,
                 ),
                 child: DecoratedBox(
                   position: DecorationPosition.foreground,
                   decoration: BoxDecoration(
-                    border: borderWidth <= 0.0
+                    border: borderWidth <= 0.0 || style._borderColor == null
                         ? null
                         : Border.all(
-                            color: style.borderColor!,
+                            color: style._borderColor!.value,
                             width: borderWidth,
                           ),
-                    borderRadius: style.borderRadius,
+                    borderRadius: style._borderRadius?.value,
                   ),
                   child: ClipRRect(
-                    borderRadius: style.borderRadius!,
+                    borderRadius:
+                        style._borderRadius?.value ?? BorderRadius.zero,
                     child: child,
                   ),
                 ),
@@ -1124,12 +1130,15 @@ class AnimatedToggleSwitch<T extends Object?>
     Widget Function(V value) builder,
     GlobalToggleProperties<T> properties,
   ) {
-    switch (animationType) {
-      case AnimationType.onSelected:
-        V currentValue = valueProvider(
+    currentValueProvider() => valueProvider(
           StyledToggleProperties(
               value: current, index: values.indexOf(current)),
         );
+    switch (animationType) {
+      case AnimationType.none:
+        return builder(currentValueProvider());
+      case AnimationType.onSelected:
+        V currentValue = currentValueProvider();
         return TweenAnimationBuilder<V>(
           curve: animationCurve,
           duration: animationDuration,
@@ -1151,16 +1160,16 @@ class AnimatedToggleSwitch<T extends Object?>
   }
 
   Widget _indicatorBuilder(BuildContext context,
-      DetailedGlobalToggleProperties<T> properties, ToggleStyle style) {
+      DetailedGlobalToggleProperties<T> properties, _BaseToggleStyle style) {
     final child = foregroundIndicatorIconBuilder?.call(context, properties);
-    return _animationTypeBuilder<ToggleStyle>(
+    return _animationTypeBuilder<_BaseToggleStyle>(
       context,
       indicatorAnimationType,
       (local) => style._merge(
         _styleBuilder(context, local, properties),
         _indicatorBorderRadiusDifference,
       ),
-      ToggleStyle._lerp,
+      _BaseToggleStyle._lerpFunction(indicatorAnimationType),
       (style) => _customIndicatorBuilder(context, style, child, properties),
       properties,
     );
@@ -1169,14 +1178,24 @@ class AnimatedToggleSwitch<T extends Object?>
   Widget _animatedIcon(BuildContext context, AnimatedToggleProperties<T> local,
       DetailedGlobalToggleProperties<T> global) {
     return Opacity(
-        opacity: 1.0 - global.loadingAnimationValue.clamp(0.0, 1.0),
-        child: Center(child: animatedIconBuilder!(context, local, global)));
+      opacity: 1.0 - global.loadingAnimationValue.clamp(0.0, 1.0),
+      child: Center(child: animatedIconBuilder!(context, local, global)),
+    );
   }
 
   Widget _animatedSizeIcon(BuildContext context, LocalToggleProperties<T> local,
       DetailedGlobalToggleProperties<T> global) {
     if (animatedIconBuilder == null) return const SizedBox();
     switch (iconAnimationType) {
+      case AnimationType.none:
+        return _animatedIcon(
+          context,
+          AnimatedToggleProperties._fromLocal(
+            animationValue: local.value == global.current ? 1.0 : 0.0,
+            properties: local,
+          ),
+          global,
+        );
       case AnimationType.onSelected:
         double currentTweenValue = local.value == global.current ? 1.0 : 0.0;
         return TweenAnimationBuilder<double>(
@@ -1225,16 +1244,17 @@ class AnimatedToggleSwitch<T extends Object?>
           );
   }
 
-  Widget _customIndicatorBuilder(BuildContext context, ToggleStyle style,
+  Widget _customIndicatorBuilder(BuildContext context, _BaseToggleStyle style,
       Widget? child, DetailedGlobalToggleProperties<T> global) {
     final loadingValue = global.loadingAnimationValue.clamp(0.0, 1.0);
     return DecoratedBox(
+        key: AnimatedToggleSwitchTestKeys.indicatorDecoratedBoxKey,
         decoration: BoxDecoration(
-          color: style.indicatorColor,
-          gradient: style.indicatorGradient,
-          borderRadius: style.indicatorBorderRadius,
-          border: style.indicatorBorder,
-          boxShadow: style.indicatorBoxShadow,
+          color: style._indicatorColor?.value,
+          gradient: style._indicatorGradient?.value,
+          borderRadius: style._indicatorBorderRadius?.value,
+          border: style._indicatorBorder?.value,
+          boxShadow: style._indicatorBoxShadow?.value,
         ),
         child: Center(
           child: Stack(
@@ -1276,7 +1296,7 @@ class _CustomClipRectState extends State<_CustomClipRect> {
 
   @override
   Widget build(BuildContext context) {
-    Widget child = _WidgetWrapper(key: _childKey, child: widget.child);
+    Widget child = _EmptyWidget(key: _childKey, child: widget.child);
     if (widget.clipBehavior == Clip.none) return child;
     return ClipRect(
       clipBehavior: widget.clipBehavior,
@@ -1285,17 +1305,6 @@ class _CustomClipRectState extends State<_CustomClipRect> {
   }
 }
 
-class _WidgetWrapper extends StatelessWidget {
-  final Widget child;
-
-  const _WidgetWrapper({Key? key, required this.child}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return child;
-  }
-}
-
 class _MyLoading extends StatelessWidget {
   const _MyLoading({Key? key}) : super(key: key);
 
diff --git a/lib/src/widgets/animation_type_builder.dart b/lib/src/widgets/animation_type_builder.dart
index a26f611..d80c3d5 100644
--- a/lib/src/widgets/animation_type_builder.dart
+++ b/lib/src/widgets/animation_type_builder.dart
@@ -9,6 +9,7 @@ class _AnimationTypeHoverBuilder<T, V> extends StatefulWidget {
   final Curve animationCurve;
   final Duration indicatorAppearingDuration;
   final Curve indicatorAppearingCurve;
+  final bool animateExternalChanges;
 
   const _AnimationTypeHoverBuilder({
     required this.valueProvider,
@@ -19,6 +20,7 @@ class _AnimationTypeHoverBuilder<T, V> extends StatefulWidget {
     required this.animationCurve,
     required this.indicatorAppearingDuration,
     required this.indicatorAppearingCurve,
+    this.animateExternalChanges = true,
   });
 
   @override
diff --git a/lib/src/widgets/conditional_wrapper.dart b/lib/src/widgets/conditional_wrapper.dart
index 88a02f1..6abcba4 100644
--- a/lib/src/widgets/conditional_wrapper.dart
+++ b/lib/src/widgets/conditional_wrapper.dart
@@ -27,6 +27,27 @@ class _ConditionalWrapperState extends State<_ConditionalWrapper> {
     return child;
   }
 }
+
+//ignore: unused_element
+class _ConditionalOpacity extends StatelessWidget {
+  final double opacity;
+  final Widget Function(BuildContext context) builder;
+
+  const _ConditionalOpacity({required this.opacity, required this.builder});
+
+  @override
+  Widget build(BuildContext context) {
+    return _ConditionalWrapper(
+      wrapper: (context, child) => Opacity(
+        opacity: opacity,
+        child: builder(context),
+      ),
+      condition: opacity > 0.0,
+      child: const SizedBox(),
+    );
+  }
+}
+
 // coverage:ignore-end
 
 class _EmptyWidget extends StatelessWidget {
diff --git a/lib/src/widgets/custom_animated_toggle_switch.dart b/lib/src/widgets/custom_animated_toggle_switch.dart
index 86c4ffc..55b058b 100644
--- a/lib/src/widgets/custom_animated_toggle_switch.dart
+++ b/lib/src/widgets/custom_animated_toggle_switch.dart
@@ -116,6 +116,8 @@ class CustomAnimatedToggleSwitch<T extends Object?> extends StatefulWidget {
   final ChangeCallback<T>? onChanged;
 
   /// Space between adjacent icons.
+  ///
+  /// This value can only be negative if [iconArrangement] is set to [IconArrangement.overlap].
   final double spacing;
 
   /// Builder for divider or other separators between the icons.


Test patch:
diff --git a/lib/src/test_keys.dart b/lib/src/test_keys.dart
new file mode 100644
index 0000000..dbfd208
--- /dev/null
+++ b/lib/src/test_keys.dart
@@ -0,0 +1,12 @@
+import 'package:flutter/foundation.dart';
+
+/// This class should only be used in the animated_toggle_switch package itself or in its tests.
+abstract class AnimatedToggleSwitchTestKeys {
+  const AnimatedToggleSwitchTestKeys._();
+
+  static const Key indicatorDecoratedBoxKey = _AnimatedToggleSwitchKey(0);
+}
+
+class _AnimatedToggleSwitchKey<T> extends ValueKey<T> {
+  const _AnimatedToggleSwitchKey(super.value);
+}
diff --git a/test/helper.dart b/test/helper.dart
index d97e175..2fa1469 100644
--- a/test/helper.dart
+++ b/test/helper.dart
@@ -88,6 +88,8 @@ typedef SwitchBuilder<T> = AnimatedToggleSwitch<T> Function({
   SeparatorBuilder? separatorBuilder,
   FittingMode? fittingMode,
   Size? indicatorSize,
+  AnimationType? indicatorAnimationType,
+  AnimationType? iconAnimationType,
 });
 
 typedef SimpleSwitchBuilder<T> = AnimatedToggleSwitch<T> Function({
@@ -108,6 +110,8 @@ typedef SimpleSwitchBuilder<T> = AnimatedToggleSwitch<T> Function({
   SeparatorBuilder? separatorBuilder,
   FittingMode? fittingMode,
   Size? indicatorSize,
+  AnimationType? indicatorAnimationType,
+  AnimationType? iconAnimationType,
 });
 
 /// Tests all AnimatedToggleSwitch constructors
@@ -120,6 +124,7 @@ void defaultTestAllSwitches(
           List<int> values)
       test, {
   bool testDual = true,
+  bool testRolling = true,
   bool testCustom = true,
   bool testSize = true,
 }) {
@@ -150,6 +155,8 @@ void defaultTestAllSwitches(
         SeparatorBuilder? separatorBuilder,
         FittingMode? fittingMode,
         Size? indicatorSize,
+        AnimationType? indicatorAnimationType,
+        AnimationType? iconAnimationType,
       }) =>
           buildSwitch(
         current: current,
@@ -170,10 +177,13 @@ void defaultTestAllSwitches(
         separatorBuilder: separatorBuilder,
         fittingMode: fittingMode,
         indicatorSize: indicatorSize,
+        indicatorAnimationType: indicatorAnimationType,
+        iconAnimationType: iconAnimationType,
       ),
       type,
       defaultValues,
     ),
+    testRolling: testRolling,
     testCustom: testCustom,
     testSize: testSize,
   );
@@ -201,6 +211,8 @@ void defaultTestAllSwitches(
           SeparatorBuilder? separatorBuilder,
           FittingMode? fittingMode,
           Size? indicatorSize,
+          AnimationType? indicatorAnimationType,
+          AnimationType? iconAnimationType,
         }) =>
             AnimatedToggleSwitch<int>.dual(
           current: current,
@@ -224,6 +236,8 @@ void defaultTestAllSwitches(
           spacing: spacing ?? 40,
           fittingMode: fittingMode ?? FittingMode.preventHorizontalOverlapping,
           indicatorSize: indicatorSize ?? const Size.fromWidth(46.0),
+          indicatorAnimationType:
+              indicatorAnimationType ?? AnimationType.onHover,
         ),
         ConstructorType.dual,
         values,
@@ -238,110 +252,122 @@ void testAllSwitches<T>(
   FutureOr<void> Function(WidgetTester tester, SwitchBuilder<T> buildSwitch,
           ConstructorType type)
       test, {
+  bool testRolling = true,
   bool testCustom = true,
   bool testSize = true,
 }) {
-  testWidgets(
-      '$description (AnimatedToggleSwitch.rolling)',
-      (tester) async => await test(
-            tester,
-            ({
-              required T current,
-              required List<T> values,
-              TestIconBuilder<T>? iconBuilder,
-              List<Widget>? iconList,
-              TextDirection? textDirection,
-              ChangeCallback<T>? onChanged,
-              TapCallback<T>? onTap,
-              bool? loading,
-              bool allowUnlistedValues = false,
-              ToggleStyle? style,
-              StyleBuilder<T>? styleBuilder,
-              CustomStyleBuilder<T>? customStyleBuilder,
-              List<ToggleStyle>? styleList,
-              bool? iconsTappable,
-              double? spacing,
-              SeparatorBuilder? separatorBuilder,
-              FittingMode? fittingMode,
-              Size? indicatorSize,
-            }) =>
-                AnimatedToggleSwitch<T>.rolling(
-              current: current,
-              values: values,
-              iconBuilder: iconBuilder,
-              iconList: iconList,
-              textDirection: textDirection,
-              onTap: onTap,
-              onChanged: onChanged,
-              loadingIconBuilder: _loadingIconBuilder,
-              loading: loading,
-              allowUnlistedValues: allowUnlistedValues,
-              style: style ?? const ToggleStyle(),
-              styleBuilder: styleBuilder,
-              customStyleBuilder: customStyleBuilder,
-              styleList: styleList,
-              iconsTappable: iconsTappable ?? true,
-              spacing: spacing ?? 0.0,
-              separatorBuilder: separatorBuilder,
-              fittingMode:
-                  fittingMode ?? FittingMode.preventHorizontalOverlapping,
-              indicatorSize: indicatorSize ?? const Size.fromWidth(46.0),
-            ),
-            ConstructorType.rolling,
-          ));
+  if (testRolling) {
+    testWidgets(
+        '$description (AnimatedToggleSwitch.rolling)',
+        (tester) async => await test(
+              tester,
+              ({
+                required T current,
+                required List<T> values,
+                TestIconBuilder<T>? iconBuilder,
+                List<Widget>? iconList,
+                TextDirection? textDirection,
+                ChangeCallback<T>? onChanged,
+                TapCallback<T>? onTap,
+                bool? loading,
+                bool allowUnlistedValues = false,
+                ToggleStyle? style,
+                StyleBuilder<T>? styleBuilder,
+                CustomStyleBuilder<T>? customStyleBuilder,
+                List<ToggleStyle>? styleList,
+                bool? iconsTappable,
+                double? spacing,
+                SeparatorBuilder? separatorBuilder,
+                FittingMode? fittingMode,
+                Size? indicatorSize,
+                AnimationType? indicatorAnimationType,
+                AnimationType? iconAnimationType,
+              }) =>
+                  AnimatedToggleSwitch<T>.rolling(
+                current: current,
+                values: values,
+                iconBuilder: iconBuilder,
+                iconList: iconList,
+                textDirection: textDirection,
+                onTap: onTap,
+                onChanged: onChanged,
+                loadingIconBuilder: _loadingIconBuilder,
+                loading: loading,
+                allowUnlistedValues: allowUnlistedValues,
+                style: style ?? const ToggleStyle(),
+                styleBuilder: styleBuilder,
+                customStyleBuilder: customStyleBuilder,
+                styleList: styleList,
+                iconsTappable: iconsTappable ?? true,
+                spacing: spacing ?? 0.0,
+                separatorBuilder: separatorBuilder,
+                fittingMode:
+                    fittingMode ?? FittingMode.preventHorizontalOverlapping,
+                indicatorSize: indicatorSize ?? const Size.fromWidth(46.0),
+                indicatorAnimationType:
+                    indicatorAnimationType ?? AnimationType.onHover,
+              ),
+              ConstructorType.rolling,
+            ));
 
-  testWidgets(
-      '$description (AnimatedToggleSwitch.rollingByHeight)',
-      (tester) async => await test(
-            tester,
-            ({
-              required T current,
-              required List<T> values,
-              TestIconBuilder<T>? iconBuilder,
-              List<Widget>? iconList,
-              TextDirection? textDirection,
-              ChangeCallback<T>? onChanged,
-              TapCallback<T>? onTap,
-              bool? loading,
-              bool allowUnlistedValues = false,
-              ToggleStyle? style,
-              StyleBuilder<T>? styleBuilder,
-              CustomStyleBuilder<T>? customStyleBuilder,
-              List<ToggleStyle>? styleList,
-              bool? iconsTappable,
-              double? spacing,
-              SeparatorBuilder? separatorBuilder,
-              FittingMode? fittingMode,
-              Size? indicatorSize,
-            }) =>
-                AnimatedToggleSwitch<T>.rollingByHeight(
-              current: current,
-              values: values,
-              iconBuilder: iconBuilder,
-              iconList: iconList,
-              textDirection: textDirection,
-              onChanged: onChanged,
-              onTap: onTap,
-              loadingIconBuilder: _loadingIconBuilder,
-              loading: loading,
-              allowUnlistedValues: allowUnlistedValues,
-              style: style ?? const ToggleStyle(),
-              styleBuilder: styleBuilder,
-              customStyleBuilder: customStyleBuilder,
-              styleList: styleList,
-              iconsTappable: iconsTappable ?? true,
-              spacing: _convertToByHeightValue(spacing ?? 0.0, 50.0, 2.0),
-              separatorBuilder: separatorBuilder,
-              fittingMode:
-                  fittingMode ?? FittingMode.preventHorizontalOverlapping,
-              indicatorSize: indicatorSize == null
-                  ? const Size.square(1.0)
-                  : Size(
-                      _convertToByHeightValue(indicatorSize.width, 50.0, 2.0),
-                      _convertToByHeightValue(indicatorSize.height, 50.0, 2.0)),
-            ),
-            ConstructorType.rolling,
-          ));
+    testWidgets(
+        '$description (AnimatedToggleSwitch.rollingByHeight)',
+        (tester) async => await test(
+              tester,
+              ({
+                required T current,
+                required List<T> values,
+                TestIconBuilder<T>? iconBuilder,
+                List<Widget>? iconList,
+                TextDirection? textDirection,
+                ChangeCallback<T>? onChanged,
+                TapCallback<T>? onTap,
+                bool? loading,
+                bool allowUnlistedValues = false,
+                ToggleStyle? style,
+                StyleBuilder<T>? styleBuilder,
+                CustomStyleBuilder<T>? customStyleBuilder,
+                List<ToggleStyle>? styleList,
+                bool? iconsTappable,
+                double? spacing,
+                SeparatorBuilder? separatorBuilder,
+                FittingMode? fittingMode,
+                Size? indicatorSize,
+                AnimationType? indicatorAnimationType,
+                AnimationType? iconAnimationType,
+              }) =>
+                  AnimatedToggleSwitch<T>.rollingByHeight(
+                current: current,
+                values: values,
+                iconBuilder: iconBuilder,
+                iconList: iconList,
+                textDirection: textDirection,
+                onChanged: onChanged,
+                onTap: onTap,
+                loadingIconBuilder: _loadingIconBuilder,
+                loading: loading,
+                allowUnlistedValues: allowUnlistedValues,
+                style: style ?? const ToggleStyle(),
+                styleBuilder: styleBuilder,
+                customStyleBuilder: customStyleBuilder,
+                styleList: styleList,
+                iconsTappable: iconsTappable ?? true,
+                spacing: _convertToByHeightValue(spacing ?? 0.0, 50.0, 2.0),
+                separatorBuilder: separatorBuilder,
+                fittingMode:
+                    fittingMode ?? FittingMode.preventHorizontalOverlapping,
+                indicatorSize: indicatorSize == null
+                    ? const Size.square(1.0)
+                    : Size(
+                        _convertToByHeightValue(indicatorSize.width, 50.0, 2.0),
+                        _convertToByHeightValue(
+                            indicatorSize.height, 50.0, 2.0)),
+                indicatorAnimationType:
+                    indicatorAnimationType ?? AnimationType.onHover,
+              ),
+              ConstructorType.rolling,
+            ));
+  }
   if (testSize) {
     testWidgets(
         '$description (AnimatedToggleSwitch.size)',
@@ -366,6 +392,8 @@ void testAllSwitches<T>(
                 SeparatorBuilder? separatorBuilder,
                 FittingMode? fittingMode,
                 Size? indicatorSize,
+                AnimationType? indicatorAnimationType,
+                AnimationType? iconAnimationType,
               }) =>
                   AnimatedToggleSwitch<T>.size(
                 current: current,
@@ -391,6 +419,8 @@ void testAllSwitches<T>(
                 fittingMode:
                     fittingMode ?? FittingMode.preventHorizontalOverlapping,
                 indicatorSize: indicatorSize ?? const Size.fromWidth(46.0),
+                indicatorAnimationType:
+                    indicatorAnimationType ?? AnimationType.onHover,
               ),
               ConstructorType.size,
             ));
@@ -417,6 +447,8 @@ void testAllSwitches<T>(
                 SeparatorBuilder? separatorBuilder,
                 FittingMode? fittingMode,
                 Size? indicatorSize,
+                AnimationType? indicatorAnimationType,
+                AnimationType? iconAnimationType,
               }) =>
                   AnimatedToggleSwitch<T>.sizeByHeight(
                 current: current,
@@ -447,6 +479,8 @@ void testAllSwitches<T>(
                         _convertToByHeightValue(indicatorSize.width, 50.0, 2.0),
                         _convertToByHeightValue(
                             indicatorSize.height, 50.0, 2.0)),
+                indicatorAnimationType:
+                    indicatorAnimationType ?? AnimationType.onHover,
               ),
               ConstructorType.size,
             ));
@@ -475,6 +509,8 @@ void testAllSwitches<T>(
                 SeparatorBuilder? separatorBuilder,
                 FittingMode? fittingMode,
                 Size? indicatorSize,
+                AnimationType? indicatorAnimationType,
+                AnimationType? iconAnimationType,
               }) =>
                   AnimatedToggleSwitch<T>.custom(
                 current: current,
@@ -499,6 +535,10 @@ void testAllSwitches<T>(
                 fittingMode:
                     fittingMode ?? FittingMode.preventHorizontalOverlapping,
                 indicatorSize: indicatorSize ?? const Size.fromWidth(46.0),
+                indicatorAnimationType:
+                    indicatorAnimationType ?? AnimationType.onHover,
+                iconAnimationType:
+                    iconAnimationType ?? AnimationType.onSelected,
               ),
               ConstructorType.custom,
             ));
@@ -525,6 +565,8 @@ void testAllSwitches<T>(
                 SeparatorBuilder? separatorBuilder,
                 FittingMode? fittingMode,
                 Size? indicatorSize,
+                AnimationType? indicatorAnimationType,
+                AnimationType? iconAnimationType,
               }) =>
                   AnimatedToggleSwitch<T>.customByHeight(
                 current: current,
@@ -554,6 +596,10 @@ void testAllSwitches<T>(
                         _convertToByHeightValue(indicatorSize.width, 50.0, 2.0),
                         _convertToByHeightValue(
                             indicatorSize.height, 50.0, 2.0)),
+                indicatorAnimationType:
+                    indicatorAnimationType ?? AnimationType.onHover,
+                iconAnimationType:
+                    iconAnimationType ?? AnimationType.onSelected,
               ),
               ConstructorType.custom,
             ));
diff --git a/test/style_test.dart b/test/style_test.dart
index c148730..749e36a 100644
--- a/test/style_test.dart
+++ b/test/style_test.dart
@@ -1,4 +1,6 @@
 import 'package:animated_toggle_switch/animated_toggle_switch.dart';
+import 'package:animated_toggle_switch/src/test_keys.dart';
+import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 
 import 'helper.dart';
@@ -16,4 +18,42 @@ void main() {
       throwsAssertionError,
     );
   });
+
+  defaultTestAllSwitches(
+      'Switch respects indicatorAnimationType: AnimationType.none',
+      (tester, buildSwitch, type, values) async {
+    const styleList = [
+      ToggleStyle(indicatorColor: Colors.green),
+      ToggleStyle(indicatorColor: Colors.red),
+      ToggleStyle(indicatorColor: Colors.blue),
+      ToggleStyle(indicatorColor: Colors.orange),
+    ];
+    final current = values[0];
+    final next = values[1];
+    final currentColor = styleList[0].indicatorColor;
+    final nextColor = styleList[1].indicatorColor;
+    final indicatorBoxFinder =
+        find.byKey(AnimatedToggleSwitchTestKeys.indicatorDecoratedBoxKey);
+    BoxDecoration findIndicatorBox() =>
+        (tester.firstWidget(indicatorBoxFinder) as DecoratedBox).decoration
+            as BoxDecoration;
+    await tester.pumpWidget(TestWrapper(
+      child: buildSwitch(
+        current: current,
+        iconBuilder: iconBuilder,
+        styleList: styleList,
+        indicatorAnimationType: AnimationType.none,
+      ),
+    ));
+    expect(findIndicatorBox().color, equals(currentColor));
+    await tester.pumpWidget(TestWrapper(
+      child: buildSwitch(
+        current: next,
+        iconBuilder: iconBuilder,
+        styleList: styleList,
+        indicatorAnimationType: AnimationType.none,
+      ),
+    ));
+    expect(findIndicatorBox().color, equals(nextColor));
+  }, testDual: false);
 }