mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Dark mode for CupertinoSwitch and CupertinoScrollbar, Fidelity updates (#40636)
This commit is contained in:
parent
d10034e9bc
commit
4815b26d71
@ -1 +1 @@
|
||||
ae7615ce466a548b41a0f7b9860ec453646f73e9
|
||||
0728c1b6e968602e173d0153a88d9cfb932d8c9b
|
||||
|
@ -1014,14 +1014,14 @@ const CupertinoSystemColorsData _kSystemColorsFallback = CupertinoSystemColorsDa
|
||||
darkHighContrastElevatedColor: Color.fromARGB(112, 120, 120, 128),
|
||||
),
|
||||
secondarySystemFill: CupertinoDynamicColor(
|
||||
color: Color.fromARGB(153, 60, 60, 67),
|
||||
darkColor: Color.fromARGB(153, 235, 235, 245),
|
||||
highContrastColor: Color.fromARGB(173, 60, 60, 67),
|
||||
darkHighContrastColor: Color.fromARGB(173, 235, 235, 245),
|
||||
elevatedColor: Color.fromARGB(153, 60, 60, 67),
|
||||
darkElevatedColor: Color.fromARGB(153, 235, 235, 245),
|
||||
highContrastElevatedColor: Color.fromARGB(173, 60, 60, 67),
|
||||
darkHighContrastElevatedColor: Color.fromARGB(173, 235, 235, 245),
|
||||
color: Color.fromARGB(40, 120, 120, 128),
|
||||
darkColor: Color.fromARGB(81, 120, 120, 128),
|
||||
highContrastColor: Color.fromARGB(61, 120, 120, 128),
|
||||
darkHighContrastColor: Color.fromARGB(102, 120, 120, 128),
|
||||
elevatedColor: Color.fromARGB(40, 120, 120, 128),
|
||||
darkElevatedColor: Color.fromARGB(81, 120, 120, 128),
|
||||
highContrastElevatedColor: Color.fromARGB(61, 120, 120, 128),
|
||||
darkHighContrastElevatedColor: Color.fromARGB(102, 120, 120, 128),
|
||||
),
|
||||
tertiarySystemFill: CupertinoDynamicColor(
|
||||
color: Color.fromARGB(30, 118, 118, 128),
|
||||
|
@ -8,19 +8,25 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'colors.dart';
|
||||
|
||||
// All values eyeballed.
|
||||
const Color _kScrollbarColor = Color(0x99777777);
|
||||
const double _kScrollbarMinLength = 36.0;
|
||||
const double _kScrollbarMinOverscrollLength = 8.0;
|
||||
const Radius _kScrollbarRadius = Radius.circular(1.5);
|
||||
const Radius _kScrollbarRadiusDragging = Radius.circular(4.0);
|
||||
const Duration _kScrollbarTimeToFade = Duration(milliseconds: 1200);
|
||||
const Duration _kScrollbarFadeDuration = Duration(milliseconds: 250);
|
||||
const Duration _kScrollbarResizeDuration = Duration(milliseconds: 150);
|
||||
|
||||
// These values are measured using screenshots from an iPhone XR 13.0 simulator.
|
||||
const double _kScrollbarThickness = 2.5;
|
||||
// Extracted from iOS 13.1 beta using Debug View Hierarchy.
|
||||
const Color _kScrollbarColor = CupertinoDynamicColor.withBrightness(
|
||||
color: Color(0x59000000),
|
||||
darkColor: Color(0x80FFFFFF),
|
||||
);
|
||||
const double _kScrollbarThickness = 3;
|
||||
const double _kScrollbarThicknessDragging = 8.0;
|
||||
const Radius _kScrollbarRadius = Radius.circular(1.5);
|
||||
const Radius _kScrollbarRadiusDragging = Radius.circular(4.0);
|
||||
|
||||
// This is the amount of space from the top of a vertical scrollbar to the
|
||||
// top edge of the scrollable, measured when the vertical scrollbar overscrolls
|
||||
// to the top.
|
||||
@ -101,7 +107,6 @@ class CupertinoScrollbar extends StatefulWidget {
|
||||
class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProviderStateMixin {
|
||||
final GlobalKey _customPaintKey = GlobalKey();
|
||||
ScrollbarPainter _painter;
|
||||
TextDirection _textDirection;
|
||||
|
||||
AnimationController _fadeoutAnimationController;
|
||||
Animation<double> _fadeoutOpacityAnimation;
|
||||
@ -141,15 +146,22 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_textDirection = Directionality.of(context);
|
||||
_painter = _buildCupertinoScrollbarPainter();
|
||||
if (_painter == null) {
|
||||
_painter = _buildCupertinoScrollbarPainter(context);
|
||||
}
|
||||
else {
|
||||
_painter
|
||||
..textDirection = Directionality.of(context)
|
||||
..color = CupertinoDynamicColor.resolve(_kScrollbarColor, context)
|
||||
..padding = MediaQuery.of(context).padding;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a [ScrollbarPainter] visually styled like the iOS scrollbar.
|
||||
ScrollbarPainter _buildCupertinoScrollbarPainter() {
|
||||
ScrollbarPainter _buildCupertinoScrollbarPainter(BuildContext context) {
|
||||
return ScrollbarPainter(
|
||||
color: _kScrollbarColor,
|
||||
textDirection: _textDirection,
|
||||
color: CupertinoDynamicColor.resolve(_kScrollbarColor, context),
|
||||
textDirection: Directionality.of(context),
|
||||
thickness: _thickness,
|
||||
fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
|
||||
mainAxisMargin: _kScrollbarMainAxisMargin,
|
||||
@ -353,9 +365,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
|
||||
child: CustomPaint(
|
||||
key: _customPaintKey,
|
||||
foregroundPainter: _painter,
|
||||
child: RepaintBoundary(
|
||||
child: widget.child,
|
||||
),
|
||||
child: RepaintBoundary(child: widget.child),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -474,8 +474,6 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
_drag.addPointer(event);
|
||||
}
|
||||
|
||||
final CupertinoThumbPainter _thumbPainter = CupertinoThumbPainter();
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
double visualPosition;
|
||||
@ -514,7 +512,7 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
}
|
||||
|
||||
final Offset thumbCenter = Offset(trackActive, trackCenter);
|
||||
_thumbPainter.paint(canvas, Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius));
|
||||
const CupertinoThumbPainter().paint(canvas, Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -96,8 +96,8 @@ class CupertinoSwitch extends StatefulWidget {
|
||||
|
||||
/// The color to use when this switch is on.
|
||||
///
|
||||
/// Defaults to [CupertinoColors.activeGreen] when null and ignores the
|
||||
/// [CupertinoTheme] in accordance to native iOS behavior.
|
||||
/// Defaults to [CupertinoSystemColorsData.systemGreen] when null and ignores
|
||||
/// the [CupertinoTheme] in accordance to native iOS behavior.
|
||||
final Color activeColor;
|
||||
|
||||
/// {@template flutter.cupertino.switch.dragStartBehavior}
|
||||
@ -140,7 +140,10 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
|
||||
opacity: widget.onChanged == null ? _kCupertinoSwitchDisabledOpacity : 1.0,
|
||||
child: _CupertinoSwitchRenderObjectWidget(
|
||||
value: widget.value,
|
||||
activeColor: widget.activeColor ?? CupertinoColors.activeGreen,
|
||||
activeColor: CupertinoDynamicColor.resolve(
|
||||
widget.activeColor ?? CupertinoSystemColors.of(context).systemGreen,
|
||||
context,
|
||||
),
|
||||
onChanged: widget.onChanged,
|
||||
vsync: this,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
@ -170,6 +173,7 @@ class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
return _RenderCupertinoSwitch(
|
||||
value: value,
|
||||
activeColor: activeColor,
|
||||
trackColor: CupertinoDynamicColor.resolve(CupertinoSystemColors.of(context).secondarySystemFill, context),
|
||||
onChanged: onChanged,
|
||||
textDirection: Directionality.of(context),
|
||||
vsync: vsync,
|
||||
@ -182,6 +186,7 @@ class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
renderObject
|
||||
..value = value
|
||||
..activeColor = activeColor
|
||||
..trackColor = CupertinoDynamicColor.resolve(CupertinoSystemColors.of(context).secondarySystemFill, context)
|
||||
..onChanged = onChanged
|
||||
..textDirection = Directionality.of(context)
|
||||
..vsync = vsync
|
||||
@ -200,7 +205,6 @@ 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);
|
||||
const Duration _kToggleDuration = Duration(milliseconds: 200);
|
||||
|
||||
@ -208,6 +212,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
_RenderCupertinoSwitch({
|
||||
@required bool value,
|
||||
@required Color activeColor,
|
||||
@required Color trackColor,
|
||||
ValueChanged<bool> onChanged,
|
||||
@required TextDirection textDirection,
|
||||
@required TickerProvider vsync,
|
||||
@ -217,6 +222,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
assert(vsync != null),
|
||||
_value = value,
|
||||
_activeColor = activeColor,
|
||||
_trackColor = trackColor,
|
||||
_onChanged = onChanged,
|
||||
_textDirection = textDirection,
|
||||
_vsync = vsync,
|
||||
@ -295,6 +301,16 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
Color get trackColor => _trackColor;
|
||||
Color _trackColor;
|
||||
set trackColor(Color value) {
|
||||
assert(value != null);
|
||||
if (value == _trackColor)
|
||||
return;
|
||||
_trackColor = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
ValueChanged<bool> get onChanged => _onChanged;
|
||||
ValueChanged<bool> _onChanged;
|
||||
set onChanged(ValueChanged<bool> value) {
|
||||
@ -458,8 +474,6 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
config.isToggled = _value;
|
||||
}
|
||||
|
||||
final CupertinoThumbPainter _thumbPainter = CupertinoThumbPainter();
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
final Canvas canvas = context.canvas;
|
||||
@ -478,7 +492,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
}
|
||||
|
||||
final Paint paint = Paint()
|
||||
..color = Color.lerp(_kTrackColor, activeColor, currentValue);
|
||||
..color = Color.lerp(trackColor, activeColor, currentValue);
|
||||
|
||||
final Rect trackRect = Rect.fromLTWH(
|
||||
offset.dx + (size.width - _kTrackWidth) / 2.0,
|
||||
@ -509,7 +523,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
);
|
||||
|
||||
context.pushClipRRect(needsCompositing, Offset.zero, thumbBounds, trackRRect, (PaintingContext innerContext, Offset offset) {
|
||||
_thumbPainter.paint(innerContext.canvas, thumbBounds);
|
||||
const CupertinoThumbPainter.switchThumb().paint(innerContext.canvas, thumbBounds);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -6,27 +6,62 @@ import 'package:flutter/painting.dart';
|
||||
|
||||
import 'colors.dart';
|
||||
|
||||
/// Paints an iOS-style slider thumb.
|
||||
const Color _kThumbBorderColor = Color(0x0A000000);
|
||||
|
||||
const List<BoxShadow> _kSwitchBoxShadows = <BoxShadow> [
|
||||
BoxShadow(
|
||||
color: Color(0x26000000),
|
||||
offset: Offset(0, 3),
|
||||
blurRadius: 8.0,
|
||||
),
|
||||
BoxShadow(
|
||||
color: Color(0x0F000000),
|
||||
offset: Offset(0, 3),
|
||||
blurRadius: 1.0,
|
||||
),
|
||||
];
|
||||
|
||||
const List<BoxShadow> _kSliderBoxShadows = <BoxShadow> [
|
||||
BoxShadow(
|
||||
color: Color(0x26000000),
|
||||
offset: Offset(0, 3),
|
||||
blurRadius: 8.0,
|
||||
),
|
||||
BoxShadow(
|
||||
color: Color(0x29000000),
|
||||
offset: Offset(0, 1),
|
||||
blurRadius: 1.0,
|
||||
),
|
||||
BoxShadow(
|
||||
color: Color(0x1A000000),
|
||||
offset: Offset(0, 3),
|
||||
blurRadius: 1.0,
|
||||
),
|
||||
];
|
||||
|
||||
/// Paints an iOS-style slider thumb or switch thumb.
|
||||
///
|
||||
/// Used by [CupertinoSwitch] and [CupertinoSlider].
|
||||
class CupertinoThumbPainter {
|
||||
/// Creates an object that paints an iOS-style slider thumb.
|
||||
CupertinoThumbPainter({
|
||||
const CupertinoThumbPainter({
|
||||
this.color = CupertinoColors.white,
|
||||
this.shadowColor = const Color(0x2C000000),
|
||||
}) : _shadowPaint = BoxShadow(
|
||||
color: shadowColor,
|
||||
blurRadius: 1.0,
|
||||
).toPaint();
|
||||
this.shadows = _kSliderBoxShadows,
|
||||
}) : assert(shadows != null);
|
||||
|
||||
/// Creates an object that paints an iOS-style switch thumb.
|
||||
const CupertinoThumbPainter.switchThumb({
|
||||
Color color = CupertinoColors.white,
|
||||
List<BoxShadow> shadows = _kSwitchBoxShadows,
|
||||
}) : this(color: color, shadows: shadows);
|
||||
|
||||
/// The color of the interior of the thumb.
|
||||
final Color color;
|
||||
|
||||
/// The color of the shadow case by the thumb.
|
||||
final Color shadowColor;
|
||||
|
||||
/// The paint used to draw the shadow case by the thumb.
|
||||
final Paint _shadowPaint;
|
||||
/// The list of [BoxShadow] to paint below the thumb.
|
||||
///
|
||||
/// Must not be null.
|
||||
final List<BoxShadow> shadows;
|
||||
|
||||
/// Half the default diameter of the thumb.
|
||||
static const double radius = 14.0;
|
||||
@ -44,8 +79,13 @@ class CupertinoThumbPainter {
|
||||
Radius.circular(rect.shortestSide / 2.0),
|
||||
);
|
||||
|
||||
canvas.drawRRect(rrect, _shadowPaint);
|
||||
canvas.drawRRect(rrect.shift(const Offset(0.0, 3.0)), _shadowPaint);
|
||||
for (BoxShadow shadow in shadows)
|
||||
canvas.drawRRect(rrect.shift(shadow.offset), shadow.toPaint());
|
||||
|
||||
canvas.drawRRect(
|
||||
rrect.inflate(0.5),
|
||||
Paint()..color = _kThumbBorderColor,
|
||||
);
|
||||
canvas.drawRRect(rrect, Paint()..color = color);
|
||||
}
|
||||
}
|
||||
|
@ -44,11 +44,11 @@ const double _kMinInteractiveSize = 48.0;
|
||||
class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
/// Creates a scrollbar with customizations given by construction arguments.
|
||||
ScrollbarPainter({
|
||||
@required this.color,
|
||||
@required this.textDirection,
|
||||
@required Color color,
|
||||
@required TextDirection textDirection,
|
||||
@required this.thickness,
|
||||
@required this.fadeoutOpacityAnimation,
|
||||
this.padding = EdgeInsets.zero,
|
||||
EdgeInsets padding = EdgeInsets.zero,
|
||||
this.mainAxisMargin = 0.0,
|
||||
this.crossAxisMargin = 0.0,
|
||||
this.radius,
|
||||
@ -66,16 +66,37 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
assert(minOverscrollLength == null || minOverscrollLength >= 0),
|
||||
assert(padding != null),
|
||||
assert(padding.isNonNegative),
|
||||
_color = color,
|
||||
_textDirection = textDirection,
|
||||
_padding = padding,
|
||||
minOverscrollLength = minOverscrollLength ?? minLength {
|
||||
fadeoutOpacityAnimation.addListener(notifyListeners);
|
||||
}
|
||||
|
||||
/// [Color] of the thumb. Mustn't be null.
|
||||
final Color color;
|
||||
Color get color => _color;
|
||||
Color _color;
|
||||
set color(Color value) {
|
||||
assert(value != null);
|
||||
if (color == value)
|
||||
return;
|
||||
|
||||
_color = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// [TextDirection] of the [BuildContext] which dictates the side of the
|
||||
/// screen the scrollbar appears in (the trailing side). Mustn't be null.
|
||||
final TextDirection textDirection;
|
||||
TextDirection get textDirection => _textDirection;
|
||||
TextDirection _textDirection;
|
||||
set textDirection(TextDirection value) {
|
||||
assert(value != null);
|
||||
if (textDirection == value)
|
||||
return;
|
||||
|
||||
_textDirection = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Thickness of the scrollbar in its cross-axis in logical pixels. Mustn't be null.
|
||||
double thickness;
|
||||
@ -110,7 +131,17 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
///
|
||||
/// Defaults to [EdgeInsets.zero]. Must not be null and offsets from all four
|
||||
/// directions must be greater than or equal to zero.
|
||||
final EdgeInsets padding;
|
||||
EdgeInsets get padding => _padding;
|
||||
EdgeInsets _padding;
|
||||
set padding(EdgeInsets value) {
|
||||
assert(value != null);
|
||||
if (padding == value)
|
||||
return;
|
||||
|
||||
_padding = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
||||
/// The preferred smallest size the scrollbar can shrink to when the total
|
||||
/// scrollable extent is large, the current visible viewport is small, and the
|
||||
@ -162,8 +193,8 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
}
|
||||
|
||||
Paint get _paint {
|
||||
return Paint()..color =
|
||||
color.withOpacity(color.opacity * fadeoutOpacityAnimation.value);
|
||||
return Paint()
|
||||
..color = color.withOpacity(color.opacity * fadeoutOpacityAnimation.value);
|
||||
}
|
||||
|
||||
void _paintThumbCrossAxis(Canvas canvas, Size size, double thumbOffset, double thumbExtent, AxisDirection direction) {
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
|
||||
const Color _kScrollbarColor = Color(0x99777777);
|
||||
const Color _kScrollbarColor = Color(0x59000000);
|
||||
|
||||
// The `y` offset has to be larger than `ScrollDragController._bigThresholdBreakDistance`
|
||||
// to prevent [motionStartDistanceThreshold] from affecting the actual drag distance.
|
||||
@ -42,9 +42,9 @@ void main() {
|
||||
color: _kScrollbarColor,
|
||||
rrect: RRect.fromRectAndRadius(
|
||||
const Rect.fromLTWH(
|
||||
800.0 - 3 - 2.5, // Screen width - margin - thickness.
|
||||
800.0 - 3 - 3, // Screen width - margin - thickness.
|
||||
3.0, // Initial position is the top margin.
|
||||
2.5, // Thickness.
|
||||
3, // Thickness.
|
||||
// Fraction in viewport * scrollbar height - top, bottom margin.
|
||||
600.0 / 4000.0 * (600.0 - 2 * 3),
|
||||
),
|
||||
@ -86,9 +86,9 @@ void main() {
|
||||
color: _kScrollbarColor,
|
||||
rrect: RRect.fromRectAndRadius(
|
||||
const Rect.fromLTWH(
|
||||
800.0 - 3 - 2.5, // Screen width - margin - thickness.
|
||||
800.0 - 3 - 3, // Screen width - margin - thickness.
|
||||
44 + 20 + 3.0, // nav bar height + top margin
|
||||
2.5, // Thickness.
|
||||
3, // Thickness.
|
||||
// Fraction visible * (viewport size - padding - margin)
|
||||
// where Fraction visible = (viewport size - padding) / content size
|
||||
(600.0 - 34 - 44 - 20) / 4000.0 * (600.0 - 2 * 3 - 34 - 44 - 20),
|
||||
|
@ -8,6 +8,11 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
|
||||
const CupertinoDynamicColor _kScrollbarColor = CupertinoDynamicColor.withBrightness(
|
||||
color: Color(0x59000000),
|
||||
darkColor:Color(0x80FFFFFF),
|
||||
);
|
||||
|
||||
void main() {
|
||||
const Duration _kScrollbarTimeToFade = Duration(milliseconds: 1200);
|
||||
const Duration _kScrollbarFadeDuration = Duration(milliseconds: 250);
|
||||
@ -31,14 +36,14 @@ void main() {
|
||||
// Scrollbar fully showing
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x99777777),
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
// Still there.
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x99777777),
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
|
||||
await gesture.up();
|
||||
@ -47,7 +52,44 @@ void main() {
|
||||
|
||||
// Opacity going down now.
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x77777777),
|
||||
color: _kScrollbarColor.color.withAlpha(69),
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar dark mode', (WidgetTester tester) async {
|
||||
Brightness brightness = Brightness.light;
|
||||
StateSetter setState;
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setter) {
|
||||
setState = setter;
|
||||
return MediaQuery(
|
||||
data: MediaQueryData(platformBrightness: brightness),
|
||||
child: const CupertinoScrollbar(
|
||||
child: SingleChildScrollView(child: SizedBox(width: 4000.0, height: 4000.0)),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(SingleChildScrollView)));
|
||||
await gesture.moveBy(const Offset(0.0, 10.0));
|
||||
await tester.pump();
|
||||
// Scrollbar fully showing
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
|
||||
setState(() { brightness = Brightness.dark; });
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: _kScrollbarColor.darkColor,
|
||||
));
|
||||
});
|
||||
|
||||
@ -81,7 +123,7 @@ void main() {
|
||||
// Scrollbar thumb is fully showing and scroll offset has moved by
|
||||
// scrollAmount.
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x99777777),
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
expect(scrollController.offset, scrollAmount);
|
||||
await scrollGesture.up();
|
||||
@ -111,7 +153,7 @@ void main() {
|
||||
expect(scrollController.offset, greaterThan(scrollAmount * 2));
|
||||
// The scrollbar thumb is still fully visible.
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x99777777),
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
|
||||
// Let the thumb fade out so all timers have resolved.
|
||||
@ -149,7 +191,7 @@ void main() {
|
||||
// Scrollbar thumb is fully showing and scroll offset has moved by
|
||||
// scrollAmount.
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x99777777),
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
expect(scrollController.offset, scrollAmount);
|
||||
await scrollGesture.up();
|
||||
@ -182,7 +224,7 @@ void main() {
|
||||
expect(scrollController.offset, greaterThan(scrollAmount * 2));
|
||||
// The scrollbar thumb is still fully visible.
|
||||
expect(find.byType(CupertinoScrollbar), paints..rrect(
|
||||
color: const Color(0x99777777),
|
||||
color: _kScrollbarColor.color,
|
||||
));
|
||||
|
||||
// Let the thumb fade out so all timers have resolved.
|
||||
|
@ -532,8 +532,8 @@ void main() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -544,7 +544,7 @@ void main() {
|
||||
find.byKey(switchKey),
|
||||
matchesGoldenFile(
|
||||
'switch.tap.off.png',
|
||||
version: 0,
|
||||
version: 1,
|
||||
),
|
||||
);
|
||||
|
||||
@ -558,7 +558,7 @@ void main() {
|
||||
find.byKey(switchKey),
|
||||
matchesGoldenFile(
|
||||
'switch.tap.turningOn.png',
|
||||
version: 0,
|
||||
version: 1,
|
||||
),
|
||||
);
|
||||
|
||||
@ -567,9 +567,59 @@ void main() {
|
||||
find.byKey(switchKey),
|
||||
matchesGoldenFile(
|
||||
'switch.tap.on.png',
|
||||
version: 0,
|
||||
version: 1,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Switch renders correctly in dark mode', (WidgetTester tester) async {
|
||||
final Key switchKey = UniqueKey();
|
||||
bool value = false;
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark),
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Center(
|
||||
child: RepaintBoundary(
|
||||
child: CupertinoSwitch(
|
||||
key: switchKey,
|
||||
value: value,
|
||||
dragStartBehavior: DragStartBehavior.down,
|
||||
onChanged: (bool newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
find.byKey(switchKey),
|
||||
matchesGoldenFile(
|
||||
'switch.tap.off.dark.png',
|
||||
version: 0,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(switchKey));
|
||||
expect(value, isTrue);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await expectLater(
|
||||
find.byKey(switchKey),
|
||||
matchesGoldenFile(
|
||||
'switch.tap.on.dark.png',
|
||||
version: 0,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user