Add thumb color customization to CupertinoSwitch (#86775)

This commit is contained in:
James 2021-07-29 01:39:06 +08:00 committed by GitHub
parent fca95838e6
commit 10152dbb70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 1 deletions

View file

@ -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<CupertinoSwitch> 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<bool>? 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<bool>? 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<bool>? get onChanged => _onChanged;
ValueChanged<bool>? _onChanged;
set onChanged(ValueChanged<bool>? 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);
}

View file

@ -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<CupertinoSwitch>(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<CupertinoSwitch>(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(