Unverified Commit 63c3de10 authored by LongCatIsLooong's avatar LongCatIsLooong Committed by GitHub

Timer picker fidelity revision (#38481)

* WIP

* trying out different numbers

* apply intrinsic width and height

* update

* update behavior

* documentation

* wip

* fix tests

* constants

* respect theme

* respect theme

* add new test

* add new test

* update

* review

* update golden commit hash
parent 476a4de1
ead5d5df3236f6d9e619e640029f9811e4eb0716
49f8198b72f6e12c65fe1db2e46162de0204e671
......@@ -104,22 +104,22 @@ const TextStyle _kDefaultPickerDarkTextStyle = TextStyle(
);
// Eyeballed value since it's not documented in https://developer.apple.com/design/resources/.
// Inspected on iOS 13 simulator with "Debug View Hierarchy".
const TextStyle _kDefaultDateTimePickerLightTextStyle = TextStyle(
inherit: false,
fontFamily: '.SF Pro Display',
fontSize: 21,
fontWeight: FontWeight.w300,
letterSpacing: -1.05,
fontWeight: FontWeight.normal,
color: CupertinoColors.black,
);
// Eyeballed value since it's not documented in https://developer.apple.com/design/resources/.
// Inspected on iOS 13 simulator with "Debug View Hierarchy".
const TextStyle _kDefaultDateTimePickerDarkTextStyle = TextStyle(
inherit: false,
fontFamily: '.SF Pro Display',
fontSize: 21,
fontWeight: FontWeight.w300,
letterSpacing: -1.05,
fontWeight: FontWeight.normal,
color: CupertinoColors.white,
);
......
......@@ -5,6 +5,7 @@
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -248,8 +249,8 @@ void main() {
width: 400.0,
child: CupertinoTimerPicker(
minuteInterval: 10,
secondInterval: 15,
initialTimerDuration: const Duration(hours: 10, minutes: 40, seconds: 45),
secondInterval: 12,
initialTimerDuration: const Duration(hours: 10, minutes: 40, seconds: 48),
mode: CupertinoTimerPickerMode.hms,
onTimerDurationChanged: (Duration d) {
duration = d;
......@@ -261,13 +262,13 @@ void main() {
await tester.drag(find.text('40'), _kRowOffset);
await tester.pump();
await tester.drag(find.text('45'), -_kRowOffset);
await tester.drag(find.text('48'), -_kRowOffset);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
expect(
duration,
const Duration(hours: 10, minutes: 50, seconds: 30),
const Duration(hours: 10, minutes: 50, seconds: 36),
);
});
......@@ -905,7 +906,7 @@ void main() {
CupertinoApp(
home: Center(
child: SizedBox(
width: 400,
width: 500,
height: 400,
child: RepaintBoundary(
child: CupertinoDatePicker(
......@@ -923,7 +924,7 @@ void main() {
find.byType(CupertinoDatePicker),
matchesGoldenFile(
'date_picker_test.datetime.initial.png',
version: 1,
version: 2,
),
);
......@@ -935,12 +936,142 @@ void main() {
find.byType(CupertinoDatePicker),
matchesGoldenFile(
'date_picker_test.datetime.drag.png',
version: 1,
version: 2,
),
);
});
});
testWidgets('TimerPicker golden tests', (WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
// Also check if the picker respects the theme.
theme: const CupertinoThemeData(
textTheme: CupertinoTextThemeData(
pickerTextStyle: TextStyle(
color: Color(0xFF663311),
),
),
),
home: Center(
child: SizedBox(
width: 320,
height: 216,
child: RepaintBoundary(
child: CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
initialTimerDuration: const Duration(hours: 23, minutes: 59),
onTimerDurationChanged: (_) {},
),
)
),
),
),
);
await expectLater(
find.byType(CupertinoTimerPicker),
matchesGoldenFile(
'timer_picker_test.datetime.initial.png',
version: 1,
),
);
// Slightly drag the minute component to make the current minute off-center.
await tester.drag(find.text('59'), Offset(0, _kRowOffset.dy / 2));
await tester.pump();
await expectLater(
find.byType(CupertinoTimerPicker),
matchesGoldenFile(
'timer_picker_test.datetime.drag.png',
version: 1,
),
);
});
testWidgets('TimerPicker only changes hour label after scrolling stops', (WidgetTester tester) async {
Duration duration;
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: SizedBox(
width: 320,
height: 216,
child: CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
initialTimerDuration: const Duration(hours: 2, minutes: 30),
onTimerDurationChanged: (Duration d) { duration = d; },
),
),
),
),
);
expect(duration, isNull);
expect(find.text('hour'), findsNothing);
expect(find.text('hours'), findsOneWidget);
await tester.drag(find.text('2'), Offset(0, -_kRowOffset.dy));
// Duration should change but not the label.
expect(duration?.inHours, 1);
expect(find.text('hour'), findsNothing);
expect(find.text('hours'), findsOneWidget);
await tester.pumpAndSettle();
// Now the label should change.
expect(duration?.inHours, 1);
expect(find.text('hours'), findsNothing);
expect(find.text('hour'), findsOneWidget);
});
testWidgets('TimerPicker has intrinsic width and height', (WidgetTester tester) async {
const Key key = Key('key');
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTimerPicker(
key: key,
mode: CupertinoTimerPickerMode.hm,
initialTimerDuration: const Duration(hours: 2, minutes: 30),
onTimerDurationChanged: (Duration d) {},
),
),
);
expect(tester.getSize(find.descendant(of: find.byKey(key), matching: find.byType(Row))), const Size(320, 216));
// Different modes shouldn't share state.
await tester.pumpWidget(const Placeholder());
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTimerPicker(
key: key,
mode: CupertinoTimerPickerMode.ms,
initialTimerDuration: const Duration(minutes: 30, seconds: 3),
onTimerDurationChanged: (Duration d) {},
),
),
);
expect(tester.getSize(find.descendant(of: find.byKey(key), matching: find.byType(Row))), const Size(320, 216));
// Different modes shouldn't share state.
await tester.pumpWidget(const Placeholder());
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTimerPicker(
key: key,
mode: CupertinoTimerPickerMode.hms,
initialTimerDuration: const Duration(hours: 5, minutes: 17, seconds: 19),
onTimerDurationChanged: (Duration d) {},
),
),
);
expect(tester.getSize(find.descendant(of: find.byKey(key), matching: find.byType(Row))), const Size(330, 216));
});
testWidgets('scrollController can be removed or added', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
int lastSelectedItem;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment