diff --git a/packages/flutter/lib/src/cupertino/switch.dart b/packages/flutter/lib/src/cupertino/switch.dart index 66dd714e73..cb6a42c2d3 100644 --- a/packages/flutter/lib/src/cupertino/switch.dart +++ b/packages/flutter/lib/src/cupertino/switch.dart @@ -77,7 +77,7 @@ class CupertinoSwitch extends StatefulWidget { /// change state until the parent widget rebuilds the switch with the new /// value. /// - /// If null, the switch will be displayed as disabled. + /// If null, the switch will be displayed as disabled, which has a reduced opacity. /// /// The callback provided to onChanged should update the state of the parent /// [StatefulWidget] using the [State.setState] method, so that the parent @@ -135,12 +135,15 @@ class CupertinoSwitch extends StatefulWidget { class _CupertinoSwitchState extends State with TickerProviderStateMixin { @override Widget build(BuildContext context) { - return _CupertinoSwitchRenderObjectWidget( - value: widget.value, - activeColor: widget.activeColor ?? CupertinoColors.activeGreen, - onChanged: widget.onChanged, - vsync: this, - dragStartBehavior: widget.dragStartBehavior, + return Opacity( + opacity: widget.onChanged == null ? _kCupertinoSwitchDisabledOpacity : 1.0, + child: _CupertinoSwitchRenderObjectWidget( + value: widget.value, + activeColor: widget.activeColor ?? CupertinoColors.activeGreen, + onChanged: widget.onChanged, + vsync: this, + dragStartBehavior: widget.dragStartBehavior, + ), ); } } @@ -193,6 +196,8 @@ const double _kTrackInnerEnd = _kTrackWidth - _kTrackInnerStart; const double _kTrackInnerLength = _kTrackInnerEnd - _kTrackInnerStart; const double _kSwitchWidth = 59.0; const double _kSwitchHeight = 39.0; +// Opacity of a disabled switch, as eye-balled from iOS Simulator on Mac. +const double _kCupertinoSwitchDisabledOpacity = 0.5; const Color _kTrackColor = CupertinoColors.lightBackgroundGray; const Duration _kReactionDuration = Duration(milliseconds: 300); diff --git a/packages/flutter/test/cupertino/switch_test.dart b/packages/flutter/test/cupertino/switch_test.dart index 7980226aa5..6f7d89b6fa 100644 --- a/packages/flutter/test/cupertino/switch_test.dart +++ b/packages/flutter/test/cupertino/switch_test.dart @@ -415,4 +415,102 @@ void main() { expect(value, isFalse); }); + testWidgets('Switch is translucent when disabled', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + dragStartBehavior: DragStartBehavior.down, + onChanged: null, + ), + ) + ), + ); + + expect(find.byType(Opacity), findsOneWidget); + expect(tester.widget(find.byType(Opacity).first).opacity, 0.5); + }); + + testWidgets('Switch is opaque when enabled', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + dragStartBehavior: DragStartBehavior.down, + onChanged: (bool newValue) {}, + ), + ) + ), + ); + + expect(find.byType(Opacity), findsOneWidget); + expect(tester.widget(find.byType(Opacity).first).opacity, 1.0); + }); + + testWidgets('Switch turns translucent after becoming disabled', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + dragStartBehavior: DragStartBehavior.down, + onChanged: (bool newValue) {}, + ), + ) + ), + ); + + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + dragStartBehavior: DragStartBehavior.down, + onChanged: null, + ), + ) + ), + ); + + expect(find.byType(Opacity), findsOneWidget); + expect(tester.widget(find.byType(Opacity).first).opacity, 0.5); + }); + + testWidgets('Switch turns opaque after becoming enabled', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + dragStartBehavior: DragStartBehavior.down, + onChanged: null, + ), + ) + ), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + dragStartBehavior: DragStartBehavior.down, + onChanged: (bool newValue) {}, + ), + ) + ), + ); + + expect(find.byType(Opacity), findsOneWidget); + expect(tester.widget(find.byType(Opacity).first).opacity, 1.0); + }); + }