parent
a1a360bf13
commit
8ffe7c56d7
1
AUTHORS
1
AUTHORS
@ -80,3 +80,4 @@ Ludwik Trammer <ludwik@gmail.com>
|
||||
Marian Triebe <m.triebe@live.de>
|
||||
Alexis Rouillard <contact@arouillard.fr>
|
||||
Mirko Mucaria <skogsfrae@gmail.com>
|
||||
Karol Czeryna <karol.czeryna@gmail.com>
|
||||
|
@ -912,26 +912,69 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
? (currentValue < 0.5 ? onInactiveThumbImageError : onActiveThumbImageError)
|
||||
: onInactiveThumbImageError;
|
||||
|
||||
// Paint the track
|
||||
final Paint paint = Paint()
|
||||
..color = trackColor;
|
||||
const double trackHorizontalPadding = kRadialReactionRadius - _kTrackRadius;
|
||||
|
||||
final Offset trackPaintOffset = _computeTrackPaintOffset(size, _kTrackWidth, _kTrackHeight);
|
||||
final Offset thumbPaintOffset = _computeThumbPaintOffset(trackPaintOffset, visualPosition);
|
||||
final Offset radialReactionOrigin = Offset(thumbPaintOffset.dx + _kThumbRadius, size.height / 2);
|
||||
|
||||
_paintTrackWith(canvas, paint, trackPaintOffset);
|
||||
paintRadialReaction(canvas: canvas, origin: radialReactionOrigin);
|
||||
_paintThumbWith(
|
||||
thumbPaintOffset,
|
||||
canvas,
|
||||
currentValue,
|
||||
thumbColor,
|
||||
thumbImage,
|
||||
thumbErrorListener,
|
||||
);
|
||||
}
|
||||
|
||||
/// Computes canvas offset for track's upper left corner
|
||||
Offset _computeTrackPaintOffset(Size canvasSize, double trackWidth, double trackHeight) {
|
||||
final double horizontalOffset = (canvasSize.width - _kTrackWidth) / 2.0;
|
||||
final double verticalOffset = (canvasSize.height - _kTrackHeight) / 2.0;
|
||||
|
||||
return Offset(horizontalOffset, verticalOffset);
|
||||
}
|
||||
|
||||
/// Computes canvas offset for thumb's upper left corner as if it were a
|
||||
/// square
|
||||
Offset _computeThumbPaintOffset(Offset trackPaintOffset, double visualPosition) {
|
||||
// How much thumb radius extends beyond the track
|
||||
const double additionalThumbRadius = _kThumbRadius - _kTrackRadius;
|
||||
|
||||
final double horizontalProgress = visualPosition * trackInnerLength;
|
||||
final double thumbHorizontalOffset = trackPaintOffset.dx - additionalThumbRadius + horizontalProgress;
|
||||
final double thumbVerticalOffset = trackPaintOffset.dy - additionalThumbRadius;
|
||||
|
||||
return Offset(thumbHorizontalOffset, thumbVerticalOffset);
|
||||
}
|
||||
|
||||
void _paintTrackWith(Canvas canvas, Paint paint, Offset trackPaintOffset) {
|
||||
final Rect trackRect = Rect.fromLTWH(
|
||||
trackHorizontalPadding,
|
||||
(size.height - _kTrackHeight) / 2.0,
|
||||
size.width - 2.0 * trackHorizontalPadding,
|
||||
trackPaintOffset.dx,
|
||||
trackPaintOffset.dy,
|
||||
_kTrackWidth,
|
||||
_kTrackHeight,
|
||||
);
|
||||
final RRect trackRRect = RRect.fromRectAndRadius(trackRect, const Radius.circular(_kTrackRadius));
|
||||
canvas.drawRRect(trackRRect, paint);
|
||||
|
||||
final Offset thumbPosition = Offset(
|
||||
kRadialReactionRadius + visualPosition * trackInnerLength,
|
||||
size.height / 2.0,
|
||||
final RRect trackRRect = RRect.fromRectAndRadius(
|
||||
trackRect,
|
||||
const Radius.circular(_kTrackRadius),
|
||||
);
|
||||
|
||||
paintRadialReaction(canvas: canvas, origin: thumbPosition);
|
||||
canvas.drawRRect(trackRRect, paint);
|
||||
}
|
||||
|
||||
void _paintThumbWith(
|
||||
Offset thumbPaintOffset,
|
||||
Canvas canvas,
|
||||
double currentValue,
|
||||
Color thumbColor,
|
||||
ImageProvider? thumbImage,
|
||||
ImageErrorListener? thumbErrorListener,
|
||||
) {
|
||||
try {
|
||||
_isPainting = true;
|
||||
if (_cachedThumbPainter == null || thumbColor != _cachedThumbColor || thumbImage != _cachedThumbImage || thumbErrorListener != _cachedThumbErrorListener) {
|
||||
@ -946,9 +989,10 @@ class _SwitchPainter extends ToggleablePainter {
|
||||
// The thumb contracts slightly during the animation
|
||||
final double inset = 1.0 - (currentValue - 0.5).abs() * 2.0;
|
||||
final double radius = _kThumbRadius - inset;
|
||||
|
||||
thumbPainter.paint(
|
||||
canvas,
|
||||
thumbPosition - Offset(radius, radius),
|
||||
thumbPaintOffset + Offset(0, inset),
|
||||
configuration.copyWith(size: Size.fromRadius(radius)),
|
||||
);
|
||||
} finally {
|
||||
|
@ -92,6 +92,57 @@ void main() {
|
||||
expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
|
||||
});
|
||||
|
||||
testWidgets('Switch does not get distorted upon changing constraints with parent', (WidgetTester tester) async {
|
||||
const double maxWidth = 300;
|
||||
const double maxHeight = 100;
|
||||
|
||||
const ValueKey<String> boundaryKey = ValueKey<String>('switch container');
|
||||
|
||||
Widget buildSwitch({required double width, required double height}) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: SizedBox(
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
child: RepaintBoundary(
|
||||
key: boundaryKey,
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
child: Switch(
|
||||
dragStartBehavior: DragStartBehavior.down,
|
||||
value: true,
|
||||
onChanged: (_) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildSwitch(
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
));
|
||||
await expectLater(
|
||||
find.byKey(boundaryKey),
|
||||
matchesGoldenFile('switch_test.big.on.png'),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(buildSwitch(
|
||||
width: 20,
|
||||
height: 10,
|
||||
));
|
||||
await expectLater(
|
||||
find.byKey(boundaryKey),
|
||||
matchesGoldenFile('switch_test.small.on.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Switch can drag (LTR)', (WidgetTester tester) async {
|
||||
bool value = false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user