From 10152dbb7063d3fc06224cb04b7dfd589a7eabae Mon Sep 17 00:00:00 2001 From: James <47376232+itssunyujia@users.noreply.github.com> Date: Thu, 29 Jul 2021 01:39:06 +0800 Subject: [PATCH] Add thumb color customization to CupertinoSwitch (#86775) --- .../flutter/lib/src/cupertino/switch.dart | 25 ++++++++- .../flutter/test/cupertino/switch_test.dart | 54 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/cupertino/switch.dart b/packages/flutter/lib/src/cupertino/switch.dart index 2010c29aeac..ac69dbadb10 100644 --- a/packages/flutter/lib/src/cupertino/switch.dart +++ b/packages/flutter/lib/src/cupertino/switch.dart @@ -61,6 +61,7 @@ class CupertinoSwitch extends StatefulWidget { required this.onChanged, this.activeColor, this.trackColor, + this.thumbColor, this.dragStartBehavior = DragStartBehavior.start, }) : assert(value != null), assert(dragStartBehavior != null), @@ -106,6 +107,11 @@ class CupertinoSwitch extends StatefulWidget { /// Defaults to [CupertinoColors.secondarySystemFill] when null. final Color? trackColor; + /// The color to use for the thumb of the switch. + /// + /// Defaults to [CupertinoColors.white] when null. + final Color? thumbColor; + /// {@template flutter.cupertino.CupertinoSwitch.dragStartBehavior} /// Determines the way that drag start behavior is handled. /// @@ -301,6 +307,7 @@ class _CupertinoSwitchState extends State with TickerProviderSt context, ), trackColor: CupertinoDynamicColor.resolve(widget.trackColor ?? CupertinoColors.secondarySystemFill, context), + thumbColor: CupertinoDynamicColor.resolve(widget.thumbColor ?? CupertinoColors.white, context), onChanged: widget.onChanged, textDirection: Directionality.of(context), state: this, @@ -325,6 +332,7 @@ class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget { required this.value, required this.activeColor, required this.trackColor, + required this.thumbColor, required this.onChanged, required this.textDirection, required this.state, @@ -333,6 +341,7 @@ class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget { final bool value; final Color activeColor; final Color trackColor; + final Color thumbColor; final ValueChanged? onChanged; final _CupertinoSwitchState state; final TextDirection textDirection; @@ -343,6 +352,7 @@ class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget { value: value, activeColor: activeColor, trackColor: trackColor, + thumbColor: thumbColor, onChanged: onChanged, textDirection: textDirection, state: state, @@ -355,6 +365,7 @@ class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget { ..value = value ..activeColor = activeColor ..trackColor = trackColor + ..thumbColor = thumbColor ..onChanged = onChanged ..textDirection = textDirection; } @@ -379,6 +390,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { required bool value, required Color activeColor, required Color trackColor, + required Color thumbColor, ValueChanged? onChanged, required TextDirection textDirection, required _CupertinoSwitchState state, @@ -388,6 +400,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { _value = value, _activeColor = activeColor, _trackColor = trackColor, + _thumbPainter = CupertinoThumbPainter.switchThumb(color: thumbColor), _onChanged = onChanged, _textDirection = textDirection, _state = state, @@ -428,6 +441,16 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { markNeedsPaint(); } + Color get thumbColor => _thumbPainter.color; + CupertinoThumbPainter _thumbPainter; + set thumbColor(Color value) { + assert(value != null); + if (value == thumbColor) + return; + _thumbPainter = CupertinoThumbPainter.switchThumb(color: value); + markNeedsPaint(); + } + ValueChanged? get onChanged => _onChanged; ValueChanged? _onChanged; set onChanged(ValueChanged? value) { @@ -525,7 +548,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox { ); _clipRRectLayer.layer = context.pushClipRRect(needsCompositing, Offset.zero, thumbBounds, trackRRect, (PaintingContext innerContext, Offset offset) { - const CupertinoThumbPainter.switchThumb().paint(innerContext.canvas, thumbBounds); + _thumbPainter.paint(innerContext.canvas, thumbBounds); }, oldLayer: _clipRRectLayer.layer); } diff --git a/packages/flutter/test/cupertino/switch_test.dart b/packages/flutter/test/cupertino/switch_test.dart index 392e43d5f11..c569f0f9886 100644 --- a/packages/flutter/test/cupertino/switch_test.dart +++ b/packages/flutter/test/cupertino/switch_test.dart @@ -526,6 +526,60 @@ void main() { expect(find.byType(CupertinoSwitch), paints..rrect(color: trackColor)); }); + testWidgets('Switch is using default thumb color', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + onChanged: null, + ), + ), + ), + ); + + expect(find.byType(CupertinoSwitch), findsOneWidget); + expect(tester.widget(find.byType(CupertinoSwitch)).thumbColor, null); + expect( + find.byType(CupertinoSwitch), + paints + ..rrect() + ..rrect() + ..rrect() + ..rrect() + ..rrect(color: CupertinoColors.white), + ); + }); + + testWidgets('Switch is using thumb color when set', (WidgetTester tester) async { + const Color thumbColor = Color(0xFF000000); + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CupertinoSwitch( + value: false, + thumbColor: thumbColor, + onChanged: null, + ), + ), + ), + ); + + expect(find.byType(CupertinoSwitch), findsOneWidget); + expect(tester.widget(find.byType(CupertinoSwitch)).thumbColor, thumbColor); + expect( + find.byType(CupertinoSwitch), + paints + ..rrect() + ..rrect() + ..rrect() + ..rrect() + ..rrect(color: thumbColor), + ); + }); + testWidgets('Switch is opaque when enabled', (WidgetTester tester) async { await tester.pumpWidget( Directionality(