mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Added Switch
Animation for Material 3 (#113090)
This commit is contained in:
parent
a5ee67ef86
commit
91d88336dd
@ -202,6 +202,18 @@ class _SwitchConfigM3 with _SwitchConfig {
|
||||
|
||||
@override
|
||||
double get trackWidth => ${tokens['md.comp.switch.track.width']};
|
||||
|
||||
// The thumb size at the middle of the track. Hand coded default based on the animation specs.
|
||||
@override
|
||||
Size get transitionalThumbSize => const Size(34, 22);
|
||||
|
||||
// Hand coded default based on the animation specs.
|
||||
@override
|
||||
int get toggleDuration => 300;
|
||||
|
||||
// Hand coded default based on the animation specs.
|
||||
@override
|
||||
double? get thumbOffset => null;
|
||||
}
|
||||
''';
|
||||
|
||||
|
@ -666,13 +666,8 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
|
||||
double get _trackInnerLength => widget.size.width - _kSwitchMinSize;
|
||||
|
||||
bool _isPressed = false;
|
||||
|
||||
void _handleDragStart(DragStartDetails details) {
|
||||
if (isInteractive) {
|
||||
setState(() {
|
||||
_isPressed = true;
|
||||
});
|
||||
reactionController.forward();
|
||||
}
|
||||
}
|
||||
@ -707,9 +702,6 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
} else {
|
||||
animateToValue();
|
||||
}
|
||||
setState(() {
|
||||
_isPressed = false;
|
||||
});
|
||||
reactionController.reverse();
|
||||
|
||||
}
|
||||
@ -734,6 +726,13 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
final _SwitchConfig switchConfig = theme.useMaterial3 ? _SwitchConfigM3(context) : _SwitchConfigM2();
|
||||
final SwitchThemeData defaults = theme.useMaterial3 ? _SwitchDefaultsM3(context) : _SwitchDefaultsM2(context);
|
||||
|
||||
positionController.duration = Duration(milliseconds: switchConfig.toggleDuration);
|
||||
if (theme.useMaterial3) {
|
||||
position
|
||||
..curve = Curves.easeOutBack
|
||||
..reverseCurve = Curves.easeOutBack.flipped;
|
||||
}
|
||||
|
||||
// Colors need to be resolved in selected and non selected states separately
|
||||
// so that they can be lerped between.
|
||||
final Set<MaterialState> activeStates = states..add(MaterialState.selected);
|
||||
@ -829,7 +828,6 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
..downPosition = downPosition
|
||||
..isFocused = states.contains(MaterialState.focused)
|
||||
..isHovered = states.contains(MaterialState.hovered)
|
||||
..isPressed = _isPressed || downPosition != null
|
||||
..activeColor = effectiveActiveThumbColor
|
||||
..inactiveColor = effectiveInactiveThumbColor
|
||||
..activeThumbImage = widget.activeThumbImage
|
||||
@ -847,6 +845,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
..inactiveThumbRadius = effectiveInactiveThumbRadius
|
||||
..activeThumbRadius = effectiveActiveThumbRadius
|
||||
..pressedThumbRadius = switchConfig.pressedThumbRadius
|
||||
..thumbOffset = switchConfig.thumbOffset
|
||||
..trackHeight = switchConfig.trackHeight
|
||||
..trackWidth = switchConfig.trackWidth
|
||||
..activeIconColor = effectiveActiveIconColor
|
||||
@ -854,7 +853,9 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
..activeIcon = effectiveActiveIcon
|
||||
..inactiveIcon = effectiveInactiveIcon
|
||||
..iconTheme = IconTheme.of(context)
|
||||
..thumbShadow = switchConfig.thumbShadow,
|
||||
..thumbShadow = switchConfig.thumbShadow
|
||||
..transitionalThumbSize = switchConfig.transitionalThumbSize
|
||||
..positionController = positionController,
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -862,6 +863,17 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
|
||||
}
|
||||
|
||||
class _SwitchPainter extends ToggleablePainter {
|
||||
AnimationController get positionController => _positionController!;
|
||||
AnimationController? _positionController;
|
||||
set positionController(AnimationController? value) {
|
||||
assert(value != null);
|
||||
if (value == _positionController) {
|
||||
return;
|
||||
}
|
||||
_positionController = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Icon? get activeIcon => _activeIcon;
|
||||
Icon? _activeIcon;
|
||||
set activeIcon(Icon? value) {
|
||||
@ -914,16 +926,6 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get isPressed => _isPressed!;
|
||||
bool? _isPressed;
|
||||
set isPressed(bool? value) {
|
||||
if (value == _isPressed) {
|
||||
return;
|
||||
}
|
||||
_isPressed = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
double get activeThumbRadius => _activeThumbRadius!;
|
||||
double? _activeThumbRadius;
|
||||
set activeThumbRadius(double value) {
|
||||
@ -957,6 +959,27 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
double? get thumbOffset => _thumbOffset;
|
||||
double? _thumbOffset;
|
||||
set thumbOffset(double? value) {
|
||||
if (value == _thumbOffset) {
|
||||
return;
|
||||
}
|
||||
_thumbOffset = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Size get transitionalThumbSize => _transitionalThumbSize!;
|
||||
Size? _transitionalThumbSize;
|
||||
set transitionalThumbSize(Size value) {
|
||||
assert(value != null);
|
||||
if (value == _transitionalThumbSize) {
|
||||
return;
|
||||
}
|
||||
_transitionalThumbSize = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
double get trackHeight => _trackHeight!;
|
||||
double? _trackHeight;
|
||||
set trackHeight(double value) {
|
||||
@ -1119,12 +1142,12 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
ImageErrorListener? _cachedThumbErrorListener;
|
||||
BoxPainter? _cachedThumbPainter;
|
||||
|
||||
BoxDecoration _createDefaultThumbDecoration(Color color, ImageProvider? image, ImageErrorListener? errorListener) {
|
||||
return BoxDecoration(
|
||||
ShapeDecoration _createDefaultThumbDecoration(Color color, ImageProvider? image, ImageErrorListener? errorListener) {
|
||||
return ShapeDecoration(
|
||||
color: color,
|
||||
image: image == null ? null : DecorationImage(image: image, onError: errorListener),
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: thumbShadow,
|
||||
shape: const StadiumBorder(),
|
||||
shadows: thumbShadow,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1140,6 +1163,10 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
}
|
||||
}
|
||||
|
||||
bool _stopPressAnimation = false;
|
||||
double? _pressedInactiveThumbRadius;
|
||||
double? _pressedActiveThumbRadius;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final double currentValue = position.value;
|
||||
@ -1153,10 +1180,88 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
visualPosition = currentValue;
|
||||
break;
|
||||
}
|
||||
if (reaction.status == AnimationStatus.reverse && _stopPressAnimation == false) {
|
||||
_stopPressAnimation = true;
|
||||
} else {
|
||||
_stopPressAnimation = false;
|
||||
}
|
||||
|
||||
// To get the thumb radius when the press ends, the value can be any number
|
||||
// between activeThumbRadius/inactiveThumbRadius and pressedThumbRadius.
|
||||
if (!_stopPressAnimation) {
|
||||
if (reaction.status == AnimationStatus.completed) {
|
||||
// This happens when the thumb is dragged instead of being tapped.
|
||||
_pressedInactiveThumbRadius = lerpDouble(inactiveThumbRadius, pressedThumbRadius, reaction.value);
|
||||
_pressedActiveThumbRadius = lerpDouble(activeThumbRadius, pressedThumbRadius, reaction.value);
|
||||
}
|
||||
if (currentValue == 0) {
|
||||
_pressedInactiveThumbRadius = lerpDouble(inactiveThumbRadius, pressedThumbRadius, reaction.value);
|
||||
_pressedActiveThumbRadius = activeThumbRadius;
|
||||
}
|
||||
if (currentValue == 1) {
|
||||
_pressedActiveThumbRadius = lerpDouble(activeThumbRadius, pressedThumbRadius, reaction.value);
|
||||
_pressedInactiveThumbRadius = inactiveThumbRadius;
|
||||
}
|
||||
}
|
||||
|
||||
final Size inactiveThumbSize = Size.fromRadius(_pressedInactiveThumbRadius ?? inactiveThumbRadius);
|
||||
final Size activeThumbSize = Size.fromRadius(_pressedActiveThumbRadius ?? activeThumbRadius);
|
||||
Animation<Size> thumbSizeAnimation(bool isForward) {
|
||||
List<TweenSequenceItem<Size>> thumbSizeSequence;
|
||||
if (isForward) {
|
||||
thumbSizeSequence = <TweenSequenceItem<Size>>[
|
||||
TweenSequenceItem<Size>(
|
||||
tween: Tween<Size>(begin: inactiveThumbSize, end: transitionalThumbSize)
|
||||
.chain(CurveTween(curve: const Cubic(0.31, 0.00, 0.56, 1.00))),
|
||||
weight: 11,
|
||||
),
|
||||
TweenSequenceItem<Size>(
|
||||
tween: Tween<Size>(begin: transitionalThumbSize, end: activeThumbSize)
|
||||
.chain(CurveTween(curve: const Cubic(0.20, 0.00, 0.00, 1.00))),
|
||||
weight: 72,
|
||||
),
|
||||
TweenSequenceItem<Size>(
|
||||
tween: ConstantTween<Size>(activeThumbSize),
|
||||
weight: 17,
|
||||
)
|
||||
];
|
||||
} else {
|
||||
thumbSizeSequence = <TweenSequenceItem<Size>>[
|
||||
TweenSequenceItem<Size>(
|
||||
tween: ConstantTween<Size>(inactiveThumbSize),
|
||||
weight: 17,
|
||||
),
|
||||
TweenSequenceItem<Size>(
|
||||
tween: Tween<Size>(begin: inactiveThumbSize, end: transitionalThumbSize)
|
||||
.chain(CurveTween(curve: const Cubic(0.20, 0.00, 0.00, 1.00).flipped)),
|
||||
weight: 72,
|
||||
),
|
||||
TweenSequenceItem<Size>(
|
||||
tween: Tween<Size>(begin: transitionalThumbSize, end: activeThumbSize)
|
||||
.chain(CurveTween(curve: const Cubic(0.31, 0.00, 0.56, 1.00).flipped)),
|
||||
weight: 11,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return TweenSequence<Size>(thumbSizeSequence).animate(positionController);
|
||||
}
|
||||
|
||||
Size thumbSize;
|
||||
if (reaction.status == AnimationStatus.completed) {
|
||||
thumbSize = Size.fromRadius(pressedThumbRadius);
|
||||
} else {
|
||||
if (position.status == AnimationStatus.dismissed || position.status == AnimationStatus.forward) {
|
||||
thumbSize = thumbSizeAnimation(true).value;
|
||||
} else {
|
||||
thumbSize = thumbSizeAnimation(false).value;
|
||||
}
|
||||
}
|
||||
|
||||
// The thumb contracts slightly during the animation in Material 2.
|
||||
final double inset = thumbOffset == null ? 0 : 1.0 - (currentValue - thumbOffset!).abs() * 2.0;
|
||||
thumbSize = Size(thumbSize.width - inset, thumbSize.height - inset);
|
||||
|
||||
final double thumbRadius = isPressed
|
||||
? pressedThumbRadius
|
||||
: lerpDouble(inactiveThumbRadius, activeThumbRadius, currentValue)!;
|
||||
final Color trackColor = Color.lerp(inactiveTrackColor, activeTrackColor, currentValue)!;
|
||||
final Color? trackOutlineColor = inactiveTrackOutlineColor == null ? null
|
||||
: Color.lerp(inactiveTrackOutlineColor, Colors.transparent, currentValue);
|
||||
@ -1176,8 +1281,8 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
..color = trackColor;
|
||||
|
||||
final Offset trackPaintOffset = _computeTrackPaintOffset(size, trackWidth, trackHeight);
|
||||
final Offset thumbPaintOffset = _computeThumbPaintOffset(trackPaintOffset, visualPosition);
|
||||
final Offset radialReactionOrigin = Offset(thumbPaintOffset.dx + thumbRadius, size.height / 2);
|
||||
final Offset thumbPaintOffset = _computeThumbPaintOffset(trackPaintOffset, thumbSize, visualPosition);
|
||||
final Offset radialReactionOrigin = Offset(thumbPaintOffset.dx + thumbSize.height / 2, size.height / 2);
|
||||
|
||||
_paintTrackWith(canvas, paint, trackPaintOffset, trackOutlineColor);
|
||||
paintRadialReaction(canvas: canvas, origin: radialReactionOrigin);
|
||||
@ -1188,8 +1293,9 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
thumbColor,
|
||||
thumbImage,
|
||||
thumbErrorListener,
|
||||
thumbRadius,
|
||||
thumbIcon,
|
||||
thumbSize,
|
||||
inset,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1203,14 +1309,14 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
|
||||
/// Computes canvas offset for thumb's upper left corner as if it were a
|
||||
/// square
|
||||
Offset _computeThumbPaintOffset(Offset trackPaintOffset, double visualPosition) {
|
||||
Offset _computeThumbPaintOffset(Offset trackPaintOffset, Size thumbSize, double visualPosition) {
|
||||
// How much thumb radius extends beyond the track
|
||||
final double trackRadius = trackHeight / 2;
|
||||
final double thumbRadius = isPressed ? pressedThumbRadius : lerpDouble(inactiveThumbRadius, activeThumbRadius, position.value)!;
|
||||
final double additionalThumbRadius = thumbRadius - trackRadius;
|
||||
final double additionalThumbRadius = thumbSize.height / 2 - trackRadius;
|
||||
final double additionalRectWidth = (thumbSize.width - thumbSize.height) / 2;
|
||||
|
||||
final double horizontalProgress = visualPosition * trackInnerLength;
|
||||
final double thumbHorizontalOffset = trackPaintOffset.dx - additionalThumbRadius + horizontalProgress;
|
||||
final double thumbHorizontalOffset = trackPaintOffset.dx - additionalThumbRadius - additionalRectWidth + horizontalProgress;
|
||||
final double thumbVerticalOffset = trackPaintOffset.dy - additionalThumbRadius;
|
||||
|
||||
return Offset(thumbHorizontalOffset, thumbVerticalOffset);
|
||||
@ -1258,8 +1364,9 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
Color thumbColor,
|
||||
ImageProvider? thumbImage,
|
||||
ImageErrorListener? thumbErrorListener,
|
||||
double thumbRadius,
|
||||
Icon? thumbIcon,
|
||||
Size thumbSize,
|
||||
double inset,
|
||||
) {
|
||||
try {
|
||||
_isPainting = true;
|
||||
@ -1272,14 +1379,10 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
}
|
||||
final BoxPainter thumbPainter = _cachedThumbPainter!;
|
||||
|
||||
// The thumb contracts slightly during the animation
|
||||
final double inset = 1.0 - (currentValue - 0.5).abs() * 2.0;
|
||||
final double radius = thumbRadius - inset;
|
||||
|
||||
thumbPainter.paint(
|
||||
canvas,
|
||||
thumbPaintOffset + Offset(0, inset),
|
||||
configuration.copyWith(size: Size.fromRadius(radius)),
|
||||
configuration.copyWith(size: thumbSize),
|
||||
);
|
||||
|
||||
if (thumbIcon != null && thumbIcon.icon != null) {
|
||||
@ -1314,8 +1417,9 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
text: textSpan,
|
||||
);
|
||||
textPainter.layout();
|
||||
final double additionalIconRadius = thumbRadius - iconSize / 2;
|
||||
final Offset offset = thumbPaintOffset + Offset(additionalIconRadius, additionalIconRadius);
|
||||
final double additionalHorizontalOffset = (thumbSize.width - iconSize) / 2;
|
||||
final double additionalVerticalOffset = (thumbSize.height - iconSize) / 2;
|
||||
final Offset offset = thumbPaintOffset + Offset(additionalHorizontalOffset, additionalVerticalOffset);
|
||||
|
||||
textPainter.paint(canvas, offset);
|
||||
}
|
||||
@ -1348,6 +1452,9 @@ mixin _SwitchConfig {
|
||||
List<BoxShadow>? get thumbShadow;
|
||||
MaterialStateProperty<Color?>? get trackOutlineColor;
|
||||
MaterialStateProperty<Color> get iconColor;
|
||||
double? get thumbOffset;
|
||||
Size get transitionalThumbSize;
|
||||
int get toggleDuration;
|
||||
}
|
||||
|
||||
// Hand coded defaults based on Material Design 2.
|
||||
@ -1389,6 +1496,15 @@ class _SwitchConfigM2 with _SwitchConfig {
|
||||
|
||||
@override
|
||||
double get trackWidth => 33.0;
|
||||
|
||||
@override
|
||||
double get thumbOffset => 0.5;
|
||||
|
||||
@override
|
||||
Size get transitionalThumbSize => const Size(20, 20);
|
||||
|
||||
@override
|
||||
int get toggleDuration => 200;
|
||||
}
|
||||
|
||||
class _SwitchDefaultsM2 extends SwitchThemeData {
|
||||
@ -1658,6 +1774,18 @@ class _SwitchConfigM3 with _SwitchConfig {
|
||||
|
||||
@override
|
||||
double get trackWidth => 52.0;
|
||||
|
||||
// The thumb size at the middle of the track. Hand coded default based on the animation specs.
|
||||
@override
|
||||
Size get transitionalThumbSize => const Size(34, 22);
|
||||
|
||||
// Hand coded default based on the animation specs.
|
||||
@override
|
||||
int get toggleDuration => 300;
|
||||
|
||||
// Hand coded default based on the animation specs.
|
||||
@override
|
||||
double? get thumbOffset => null;
|
||||
}
|
||||
|
||||
// END GENERATED TOKEN PROPERTIES - Switch
|
||||
|
@ -148,10 +148,10 @@ void main() {
|
||||
find.byType(Switch),
|
||||
paints
|
||||
..rrect(color: Colors.blue[500])
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.yellow[500]),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.yellow[500]),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(Switch));
|
||||
@ -161,10 +161,10 @@ void main() {
|
||||
Material.of(tester.element(find.byType(Switch))),
|
||||
paints
|
||||
..rrect(color: Colors.green[500])
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.red[500]),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.red[500]),
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -378,10 +378,10 @@ void main() {
|
||||
color: const Color(0x52000000), // Black with 32% opacity
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.grey.shade50),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.grey.shade50),
|
||||
reason: 'Inactive enabled switch should match these colors',
|
||||
);
|
||||
await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
|
||||
@ -394,10 +394,10 @@ void main() {
|
||||
color: const Color(0x802196f3),
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xff2196f3)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xff2196f3)),
|
||||
reason: 'Active enabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -428,10 +428,10 @@ void main() {
|
||||
color: Colors.black12,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.grey.shade400),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.grey.shade400),
|
||||
reason: 'Inactive disabled switch should match these colors',
|
||||
);
|
||||
|
||||
@ -460,10 +460,10 @@ void main() {
|
||||
color: Colors.black12,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.grey.shade400),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.grey.shade400),
|
||||
reason: 'Active disabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -504,10 +504,10 @@ void main() {
|
||||
color: Colors.blue[500],
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.yellow[500]),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.yellow[500]),
|
||||
);
|
||||
await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
|
||||
await tester.pump();
|
||||
@ -519,10 +519,10 @@ void main() {
|
||||
color: Colors.green[500],
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: Colors.red[500]),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: Colors.red[500]),
|
||||
);
|
||||
});
|
||||
|
||||
@ -838,10 +838,10 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: Colors.orange[500])
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xff2196f3)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xff2196f3)),
|
||||
);
|
||||
|
||||
// Check the false value.
|
||||
@ -857,10 +857,10 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: Colors.orange[500])
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xfffafafa)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xfffafafa)),
|
||||
);
|
||||
|
||||
// Check what happens when disabled.
|
||||
@ -875,10 +875,10 @@ void main() {
|
||||
color: const Color(0x1f000000),
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xffbdbdbd)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xffbdbdbd)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -942,10 +942,10 @@ void main() {
|
||||
color: const Color(0x802196f3),
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xff2196f3)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xff2196f3)),
|
||||
);
|
||||
|
||||
// Start hovering
|
||||
@ -963,10 +963,10 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: Colors.orange[500])
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xff2196f3)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xff2196f3)),
|
||||
);
|
||||
|
||||
// Check what happens when disabled.
|
||||
@ -979,10 +979,10 @@ void main() {
|
||||
color: const Color(0x1f000000),
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0xffbdbdbd)),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: const Color(0xffbdbdbd)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -1228,10 +1228,10 @@ void main() {
|
||||
color: Colors.black12,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: inactiveDisabledThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: inactiveDisabledThumbColor),
|
||||
reason: 'Inactive disabled switch should default track and custom thumb color',
|
||||
);
|
||||
|
||||
@ -1245,10 +1245,10 @@ void main() {
|
||||
color: Colors.black12,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: activeDisabledThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: activeDisabledThumbColor),
|
||||
reason: 'Active disabled switch should match these colors',
|
||||
);
|
||||
|
||||
@ -1262,10 +1262,10 @@ void main() {
|
||||
color: const Color(0x52000000), // Black with 32% opacity,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: inactiveEnabledThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: inactiveEnabledThumbColor),
|
||||
reason: 'Inactive enabled switch should match these colors',
|
||||
);
|
||||
|
||||
@ -1279,10 +1279,10 @@ void main() {
|
||||
color: Colors.black12,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: inactiveDisabledThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: inactiveDisabledThumbColor),
|
||||
reason: 'Inactive disabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -1338,10 +1338,10 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: focusedThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: focusedThumbColor),
|
||||
reason: 'Inactive disabled switch should default track and custom thumb color',
|
||||
);
|
||||
|
||||
@ -1359,10 +1359,10 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: hoveredThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: hoveredThumbColor),
|
||||
reason: 'Inactive disabled switch should default track and custom thumb color',
|
||||
);
|
||||
});
|
||||
@ -1577,10 +1577,10 @@ void main() {
|
||||
color: Colors.black12,
|
||||
rrect: RRect.fromLTRBR(13.0, 17.0, 46.0, 31.0, const Radius.circular(7.0)),
|
||||
)
|
||||
..circle(color: const Color(0x33000000))
|
||||
..circle(color: const Color(0x24000000))
|
||||
..circle(color: const Color(0x1f000000))
|
||||
..circle(color: expectedThumbColor),
|
||||
..rrect(color: const Color(0x33000000))
|
||||
..rrect(color: const Color(0x24000000))
|
||||
..rrect(color: const Color(0x1f000000))
|
||||
..rrect(color: expectedThumbColor),
|
||||
reason: 'Active disabled thumb color should be blended on top of surface color',
|
||||
);
|
||||
});
|
||||
@ -1934,6 +1934,140 @@ void main() {
|
||||
});
|
||||
|
||||
group('Switch M3 tests', () {
|
||||
testWidgets('M3 Switch has a 300-millisecond animation in total', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||
bool value = false;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: Switch(
|
||||
value: value,
|
||||
onChanged: (bool newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(value, isFalse);
|
||||
|
||||
final Rect switchRect = tester.getRect(find.byType(Switch));
|
||||
final TestGesture gesture = await tester.startGesture(switchRect.centerLeft);
|
||||
await tester.pump();
|
||||
await gesture.up();
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 200)); // M2 animation duration
|
||||
expect(tester.hasRunningAnimations, true);
|
||||
await tester.pump(const Duration(milliseconds: 101));
|
||||
expect(tester.hasRunningAnimations, false);
|
||||
});
|
||||
|
||||
testWidgets('M3 Switch has a stadium shape in the middle of the track', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true, colorSchemeSeed: Colors.deepPurple);
|
||||
bool value = false;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: Switch(
|
||||
value: value,
|
||||
onChanged: (bool newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(value, isFalse);
|
||||
|
||||
final Rect switchRect = tester.getRect(find.byType(Switch));
|
||||
final TestGesture gesture = await tester.startGesture(switchRect.centerLeft);
|
||||
await tester.pump();
|
||||
await gesture.up();
|
||||
await tester.pump();
|
||||
// After 33 milliseconds, the switch thumb moves to the middle
|
||||
// and has a stadium shape with a size of (34x22).
|
||||
await tester.pump(const Duration(milliseconds: 33));
|
||||
expect(tester.hasRunningAnimations, true);
|
||||
|
||||
await expectLater(
|
||||
find.byType(Switch),
|
||||
matchesGoldenFile('switch_test.m3.transition.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('M3 Switch thumb bounces in the end of the animation', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||
bool value = false;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: Switch(
|
||||
value: value,
|
||||
onChanged: (bool newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(value, isFalse);
|
||||
|
||||
final Rect switchRect = tester.getRect(find.byType(Switch));
|
||||
final TestGesture gesture = await tester.startGesture(switchRect.centerLeft);
|
||||
await tester.pump();
|
||||
await gesture.up();
|
||||
await tester.pump();
|
||||
// The value on y axis is greater than 1 when t > 0.375
|
||||
// 300 * 0.375 = 112.5
|
||||
await tester.pump(const Duration(milliseconds: 113));
|
||||
final ToggleableStateMixin state = tester.state<ToggleableStateMixin>(
|
||||
find.descendant(
|
||||
of: find.byType(Switch),
|
||||
matching: find.byWidgetPredicate(
|
||||
(Widget widget) => widget.runtimeType.toString() == '_MaterialSwitch',
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(tester.hasRunningAnimations, true);
|
||||
expect(state.position.value, greaterThan(1));
|
||||
});
|
||||
|
||||
testWidgets('Switch has default colors when enabled - M3', (WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
|
||||
final ColorScheme colors = theme.colorScheme;
|
||||
@ -1978,7 +2112,7 @@ void main() {
|
||||
color: colors.outline,
|
||||
rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.outline), // thumb color
|
||||
..rrect(color: colors.outline), // thumb color
|
||||
reason: 'Inactive enabled switch should match these colors',
|
||||
);
|
||||
await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
|
||||
@ -1993,7 +2127,8 @@ void main() {
|
||||
color: colors.primary,
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.onPrimary), // thumb color
|
||||
..rrect()
|
||||
..rrect(color: colors.onPrimary), // thumb color
|
||||
reason: 'Active enabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -2035,7 +2170,7 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)), // thumb color
|
||||
..rrect(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)), // thumb color
|
||||
reason: 'Inactive disabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -2073,7 +2208,8 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.surface), // thumb color
|
||||
..rrect()
|
||||
..rrect(color: colors.surface), // thumb color
|
||||
reason: 'Active disabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -2125,7 +2261,7 @@ void main() {
|
||||
style: PaintingStyle.stroke,
|
||||
color: colors.outline,
|
||||
)
|
||||
..circle(color: Colors.yellow[500]), // thumb color
|
||||
..rrect(color: Colors.yellow[500]), // thumb color
|
||||
);
|
||||
await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
|
||||
await tester.pump();
|
||||
@ -2138,7 +2274,8 @@ void main() {
|
||||
color: Colors.green[500],
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: Colors.red[500]), // thumb color
|
||||
..rrect()
|
||||
..rrect(color: Colors.red[500]), // thumb color
|
||||
);
|
||||
});
|
||||
|
||||
@ -2225,7 +2362,7 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)),
|
||||
..rrect(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -2265,7 +2402,8 @@ void main() {
|
||||
color: colors.primary,
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.onPrimary),
|
||||
..rrect()
|
||||
..rrect(color: colors.onPrimary),
|
||||
);
|
||||
|
||||
// Start hovering
|
||||
@ -2295,7 +2433,8 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.surface.withOpacity(1.0)),
|
||||
..rrect()
|
||||
..rrect(color: colors.surface.withOpacity(1.0)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -2359,7 +2498,7 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: inactiveDisabledThumbColor),
|
||||
..rrect(color: inactiveDisabledThumbColor),
|
||||
reason: 'Inactive disabled switch should default track and custom thumb color',
|
||||
);
|
||||
|
||||
@ -2374,7 +2513,8 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: activeDisabledThumbColor),
|
||||
..rrect()
|
||||
..rrect(color: activeDisabledThumbColor),
|
||||
reason: 'Active disabled switch should match these colors',
|
||||
);
|
||||
|
||||
@ -2389,7 +2529,8 @@ void main() {
|
||||
color: colors.surfaceVariant,
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: inactiveEnabledThumbColor),
|
||||
..rrect()
|
||||
..rrect(color: inactiveEnabledThumbColor),
|
||||
reason: 'Inactive enabled switch should match these colors',
|
||||
);
|
||||
|
||||
@ -2404,7 +2545,8 @@ void main() {
|
||||
color: colors.primary,
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: activeEnabledThumbColor),
|
||||
..rrect()
|
||||
..rrect(color: activeEnabledThumbColor),
|
||||
reason: 'Active enabled switch should match these colors',
|
||||
);
|
||||
});
|
||||
@ -2465,7 +2607,7 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.primary.withOpacity(0.12))
|
||||
..circle(color: focusedThumbColor),
|
||||
..rrect(color: focusedThumbColor),
|
||||
reason: 'active enabled switch should default track and custom thumb color',
|
||||
);
|
||||
|
||||
@ -2484,7 +2626,7 @@ void main() {
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: colors.primary.withOpacity(0.08))
|
||||
..circle(color: hoveredThumbColor),
|
||||
..rrect(color: hoveredThumbColor),
|
||||
reason: 'active enabled switch should default track and custom thumb color',
|
||||
);
|
||||
});
|
||||
@ -2708,7 +2850,8 @@ void main() {
|
||||
color: colors.onSurface.withOpacity(0.12),
|
||||
rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
|
||||
)
|
||||
..circle(color: expectedThumbColor),
|
||||
..rrect()
|
||||
..rrect(color: expectedThumbColor),
|
||||
reason: 'Active disabled thumb color should be blended on top of surface color',
|
||||
);
|
||||
});
|
||||
@ -2755,7 +2898,7 @@ void main() {
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(Switch))),
|
||||
paints
|
||||
..rrect()..circle()
|
||||
..rrect()..rrect()
|
||||
..paragraph(offset: const Offset(32.0, 16.0)),
|
||||
);
|
||||
|
||||
@ -2766,7 +2909,7 @@ void main() {
|
||||
Material.of(tester.element(find.byType(Switch))),
|
||||
paints
|
||||
..rrect()..rrect()
|
||||
..circle()
|
||||
..rrect()
|
||||
..paragraph(offset: const Offset(12.0, 16.0)),
|
||||
);
|
||||
|
||||
@ -2776,7 +2919,7 @@ void main() {
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(Switch))),
|
||||
paints
|
||||
..rrect()..rrect()..circle()
|
||||
..rrect()..rrect()..rrect()
|
||||
);
|
||||
|
||||
// inactive icon doesn't show when switch is on.
|
||||
@ -2785,7 +2928,7 @@ void main() {
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(Switch))),
|
||||
paints
|
||||
..rrect()..circle()..restore(),
|
||||
..rrect()..rrect()..restore(),
|
||||
);
|
||||
|
||||
// without icon
|
||||
@ -2793,7 +2936,7 @@ void main() {
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(Switch))),
|
||||
paints
|
||||
..rrect()..rrect()..circle()..restore(),
|
||||
..rrect()..rrect()..rrect()..restore(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -147,15 +147,15 @@ void main() {
|
||||
? (paints
|
||||
..rrect(color: defaultTrackColor)
|
||||
..rrect(color: themeData.colorScheme.outline)
|
||||
..circle(color: defaultThumbColor)
|
||||
..rrect(color: defaultThumbColor)
|
||||
..paragraph()
|
||||
)
|
||||
: (paints
|
||||
..rrect(color: defaultTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: defaultThumbColor)
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: defaultThumbColor)
|
||||
)
|
||||
);
|
||||
// Size from MaterialTapTargetSize.shrinkWrap.
|
||||
@ -168,14 +168,14 @@ void main() {
|
||||
_getSwitchMaterial(tester),
|
||||
material3
|
||||
? (paints
|
||||
..rrect(color: selectedTrackColor)
|
||||
..circle(color: selectedThumbColor)..paragraph())
|
||||
..rrect(color: selectedTrackColor)..rrect()
|
||||
..rrect(color: selectedThumbColor)..paragraph())
|
||||
: (paints
|
||||
..rrect(color: selectedTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: selectedThumbColor))
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: selectedThumbColor))
|
||||
);
|
||||
|
||||
// Switch with hover.
|
||||
@ -295,13 +295,13 @@ void main() {
|
||||
? (paints
|
||||
..rrect(color: defaultTrackColor)
|
||||
..rrect(color: themeData.colorScheme.outline)
|
||||
..circle(color: defaultThumbColor)..paragraph(offset: const Offset(12, 16)))
|
||||
..rrect(color: defaultThumbColor)..paragraph(offset: const Offset(12, 16)))
|
||||
: (paints
|
||||
..rrect(color: defaultTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: defaultThumbColor))
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: defaultThumbColor))
|
||||
);
|
||||
// Size from MaterialTapTargetSize.shrinkWrap.
|
||||
expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
|
||||
@ -314,13 +314,13 @@ void main() {
|
||||
material3
|
||||
? (paints
|
||||
..rrect(color: selectedTrackColor)
|
||||
..circle(color: selectedThumbColor))
|
||||
..rrect(color: selectedThumbColor))
|
||||
: (paints
|
||||
..rrect(color: selectedTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: selectedThumbColor))
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: selectedThumbColor))
|
||||
);
|
||||
|
||||
// Switch with hover.
|
||||
@ -393,13 +393,13 @@ void main() {
|
||||
? (paints
|
||||
..rrect(color: defaultTrackColor)
|
||||
..rrect(color: themeData.colorScheme.outline)
|
||||
..circle(color: defaultThumbColor))
|
||||
..rrect(color: defaultThumbColor))
|
||||
: (paints
|
||||
..rrect(color: defaultTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: defaultThumbColor))
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: defaultThumbColor))
|
||||
);
|
||||
|
||||
// Selected switch.
|
||||
@ -410,13 +410,13 @@ void main() {
|
||||
material3
|
||||
? (paints
|
||||
..rrect(color: selectedTrackColor)
|
||||
..circle(color: selectedThumbColor))
|
||||
..rrect(color: selectedThumbColor))
|
||||
: (paints
|
||||
..rrect(color: selectedTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: selectedThumbColor))
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: selectedThumbColor))
|
||||
);
|
||||
});
|
||||
|
||||
@ -532,13 +532,13 @@ void main() {
|
||||
material3
|
||||
? (paints
|
||||
..rrect(color: localThemeTrackColor)
|
||||
..circle(color: localThemeThumbColor))
|
||||
..rrect(color: localThemeThumbColor))
|
||||
: (paints
|
||||
..rrect(color: localThemeTrackColor)
|
||||
..circle()
|
||||
..circle()
|
||||
..circle()
|
||||
..circle(color: localThemeThumbColor))
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect()
|
||||
..rrect(color: localThemeThumbColor))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user