mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[time_picker] refactor: Distinguish widgets for dial mode only (#173188)
The code for time picker involves ambiguous widget names, which makes understanding the widget structure more challenging. I tried to use the namings of the [M3 specs](https://m3.material.io/components/time-pickers/specs) to make it a bit clearer. This also removes a code section which is not needed, as the widget is only meant for "dial" and not "input" mode. I didn't raise an issue, but I can, if that's still necessary. This PR is test-exempt, as it doesn't add or fix any functionality. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --------- Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
This commit is contained in:
parent
bf97b09609
commit
aa56148767
@ -238,13 +238,15 @@ class _TimePickerModel extends InheritedModel<_TimePickerAspect> {
|
||||
}
|
||||
}
|
||||
|
||||
class _TimePickerHeader extends StatelessWidget {
|
||||
const _TimePickerHeader({required this.helpText});
|
||||
/// The header for the time picker in dial mode.
|
||||
class _DialTimePickerHeader extends StatelessWidget {
|
||||
const _DialTimePickerHeader({required this.helpText});
|
||||
|
||||
final String helpText;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(_debugDialTimePickerEntryMode(context));
|
||||
final TimeOfDayFormat timeOfDayFormat = MaterialLocalizations.of(
|
||||
context,
|
||||
).timeOfDayFormat(alwaysUse24HourFormat: _TimePickerModel.use24HourFormatOf(context));
|
||||
@ -285,9 +287,9 @@ class _TimePickerHeader extends StatelessWidget {
|
||||
// Hour/minutes should not change positions in RTL locales.
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const Expanded(child: _HourControl()),
|
||||
const Expanded(child: _DialHourControl()),
|
||||
_TimeSelectorSeparator(timeOfDayFormat: timeOfDayFormat),
|
||||
const Expanded(child: _MinuteControl()),
|
||||
const Expanded(child: _DialMinuteControl()),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -316,9 +318,9 @@ class _TimePickerHeader extends StatelessWidget {
|
||||
// Hour/minutes should not change positions in RTL locales.
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const Expanded(child: _HourControl()),
|
||||
const Expanded(child: _DialHourControl()),
|
||||
_TimeSelectorSeparator(timeOfDayFormat: timeOfDayFormat),
|
||||
const Expanded(child: _MinuteControl()),
|
||||
const Expanded(child: _DialMinuteControl()),
|
||||
],
|
||||
),
|
||||
if (hourDialType == _HourDialType.twelveHour) const _DayPeriodControl(),
|
||||
@ -339,8 +341,9 @@ class _TimePickerHeader extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _HourMinuteControl extends StatelessWidget {
|
||||
const _HourMinuteControl({
|
||||
/// The control label for the time selector in dial mode.
|
||||
class _DialTimeSelectorControl extends StatelessWidget {
|
||||
const _DialTimeSelectorControl({
|
||||
required this.text,
|
||||
required this.onTap,
|
||||
required this.onDoubleTap,
|
||||
@ -354,6 +357,7 @@ class _HourMinuteControl extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(_debugDialTimePickerEntryMode(context));
|
||||
final TimePickerThemeData timePickerTheme = _TimePickerModel.themeOf(context);
|
||||
final _TimePickerDefaults defaultTheme = _TimePickerModel.defaultThemeOf(context);
|
||||
final Color backgroundColor = timePickerTheme.hourMinuteColor ?? defaultTheme.hourMinuteColor;
|
||||
@ -370,18 +374,8 @@ class _HourMinuteControl extends StatelessWidget {
|
||||
states,
|
||||
).copyWith(color: effectiveTextColor);
|
||||
|
||||
final double height;
|
||||
switch (_TimePickerModel.entryModeOf(context)) {
|
||||
case TimePickerEntryMode.dial:
|
||||
case TimePickerEntryMode.dialOnly:
|
||||
height = defaultTheme.hourMinuteSize.height;
|
||||
case TimePickerEntryMode.input:
|
||||
case TimePickerEntryMode.inputOnly:
|
||||
height = defaultTheme.hourMinuteInputSize.height;
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
height: height,
|
||||
height: defaultTheme.hourMinuteSize.height,
|
||||
child: Material(
|
||||
color: WidgetStateProperty.resolveAs(backgroundColor, states),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
@ -398,14 +392,15 @@ class _HourMinuteControl extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Displays the hour fragment.
|
||||
/// Displays the hour fragment in dial mode.
|
||||
///
|
||||
/// When tapped changes time picker dial mode to [_HourMinuteMode.hour].
|
||||
class _HourControl extends StatelessWidget {
|
||||
const _HourControl();
|
||||
class _DialHourControl extends StatelessWidget {
|
||||
const _DialHourControl();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(_debugDialTimePickerEntryMode(context));
|
||||
assert(debugCheckHasMediaQuery(context));
|
||||
final bool alwaysUse24HourFormat = MediaQuery.alwaysUse24HourFormatOf(context);
|
||||
final TimeOfDay selectedTime = _TimePickerModel.selectedTimeOf(context);
|
||||
@ -453,7 +448,7 @@ class _HourControl extends StatelessWidget {
|
||||
onDecrease: () {
|
||||
_TimePickerModel.setSelectedTime(context, previousHour);
|
||||
},
|
||||
child: _HourMinuteControl(
|
||||
child: _DialTimeSelectorControl(
|
||||
isSelected: _TimePickerModel.hourMinuteModeOf(context) == _HourMinuteMode.hour,
|
||||
text: formattedHour,
|
||||
onTap: () => _TimePickerModel.setHourMinuteMode(context, _HourMinuteMode.hour),
|
||||
@ -538,14 +533,15 @@ class _TimeSelectorSeparator extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Displays the minute fragment.
|
||||
/// Displays the minute fragment in dial mode.
|
||||
///
|
||||
/// When tapped changes time picker dial mode to [_HourMinuteMode.minute].
|
||||
class _MinuteControl extends StatelessWidget {
|
||||
const _MinuteControl();
|
||||
class _DialMinuteControl extends StatelessWidget {
|
||||
const _DialMinuteControl();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(_debugDialTimePickerEntryMode(context));
|
||||
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
|
||||
final TimeOfDay selectedTime = _TimePickerModel.selectedTimeOf(context);
|
||||
final String formattedMinute = localizations.formatMinute(selectedTime);
|
||||
@ -569,7 +565,7 @@ class _MinuteControl extends StatelessWidget {
|
||||
onDecrease: () {
|
||||
_TimePickerModel.setSelectedTime(context, previousMinute);
|
||||
},
|
||||
child: _HourMinuteControl(
|
||||
child: _DialTimeSelectorControl(
|
||||
isSelected: _TimePickerModel.hourMinuteModeOf(context) == _HourMinuteMode.minute,
|
||||
text: formattedMinute,
|
||||
onTap: () => _TimePickerModel.setHourMinuteMode(context, _HourMinuteMode.minute),
|
||||
@ -1612,6 +1608,7 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(_debugDialTimePickerEntryMode(context));
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final TimePickerThemeData timePickerTheme = TimePickerTheme.of(context);
|
||||
final _TimePickerDefaults defaultTheme = theme.useMaterial3
|
||||
@ -3064,7 +3061,7 @@ class _TimePickerState extends State<_TimePicker> with RestorationMixin {
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: theme.useMaterial3 ? 0 : 16),
|
||||
child: _TimePickerHeader(helpText: helpText),
|
||||
child: _DialTimePickerHeader(helpText: helpText),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
@ -3091,7 +3088,7 @@ class _TimePickerState extends State<_TimePicker> with RestorationMixin {
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
_TimePickerHeader(helpText: helpText),
|
||||
_DialTimePickerHeader(helpText: helpText),
|
||||
Expanded(child: dial),
|
||||
],
|
||||
),
|
||||
@ -3621,6 +3618,12 @@ class _TimePickerDefaultsM2 extends _TimePickerDefaults {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure the widget is called in [TimePickerEntryMode.dial] or [TimePickerEntryMode.dialOnly] mode.
|
||||
bool _debugDialTimePickerEntryMode(BuildContext context) {
|
||||
final TimePickerEntryMode entryMode = _TimePickerModel.entryModeOf(context);
|
||||
return entryMode == TimePickerEntryMode.dial || entryMode == TimePickerEntryMode.dialOnly;
|
||||
}
|
||||
|
||||
// BEGIN GENERATED TOKEN PROPERTIES - TimePicker
|
||||
|
||||
// Do not edit by hand. The code between the "BEGIN GENERATED" and
|
||||
|
||||
@ -1589,13 +1589,13 @@ void main() {
|
||||
final SemanticsNode elevenHours = semantics
|
||||
.nodesWith(
|
||||
value: 'Select hours $initialValue',
|
||||
ancestor: tester.renderObject(_hourControl).debugSemantics,
|
||||
ancestor: tester.renderObject(_dialHourControl).debugSemantics,
|
||||
)
|
||||
.single;
|
||||
tester.binding.pipelineOwner.semanticsOwner!.performAction(elevenHours.id, action);
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
find.descendant(of: _hourControl, matching: find.text(finalValue)),
|
||||
find.descendant(of: _dialHourControl, matching: find.text(finalValue)),
|
||||
findsOneWidget,
|
||||
);
|
||||
}
|
||||
@ -1643,13 +1643,13 @@ void main() {
|
||||
final SemanticsNode elevenHours = semantics
|
||||
.nodesWith(
|
||||
value: 'Select minutes $initialValue',
|
||||
ancestor: tester.renderObject(_minuteControl).debugSemantics,
|
||||
ancestor: tester.renderObject(_dialMinuteControl).debugSemantics,
|
||||
)
|
||||
.single;
|
||||
tester.binding.pipelineOwner.semanticsOwner!.performAction(elevenHours.id, action);
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
find.descendant(of: _minuteControl, matching: find.text(finalValue)),
|
||||
find.descendant(of: _dialMinuteControl, matching: find.text(finalValue)),
|
||||
findsOneWidget,
|
||||
);
|
||||
}
|
||||
@ -2660,11 +2660,11 @@ Future<void> mediaQueryBoilerplate(
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
final Finder _hourControl = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourControl',
|
||||
final Finder _dialHourControl = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialHourControl',
|
||||
);
|
||||
final Finder _minuteControl = find.byWidgetPredicate(
|
||||
(Widget widget) => '${widget.runtimeType}' == '_MinuteControl',
|
||||
final Finder _dialMinuteControl = find.byWidgetPredicate(
|
||||
(Widget widget) => '${widget.runtimeType}' == '_DialMinuteControl',
|
||||
);
|
||||
final Finder _timePicker = find.byWidgetPredicate(
|
||||
(Widget widget) => '${widget.runtimeType}' == '_TimePicker',
|
||||
|
||||
@ -26,11 +26,11 @@ void main() {
|
||||
matching: find.byType(Text),
|
||||
)
|
||||
.first;
|
||||
final Finder hourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourControl',
|
||||
final Finder dialHourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialHourControl',
|
||||
);
|
||||
final Finder minuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MinuteControl',
|
||||
final Finder dialMinuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialMinuteControl',
|
||||
);
|
||||
final Finder dayPeriodControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DayPeriodControl',
|
||||
@ -54,8 +54,8 @@ void main() {
|
||||
useMaterial3: false,
|
||||
);
|
||||
final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
|
||||
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
|
||||
final double hourLeftOffset = tester.getTopLeft(dialHourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(dialMinuteControlFinder).dx;
|
||||
final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
|
||||
|
||||
if (locale == const Locale('en', 'US')) {
|
||||
@ -111,11 +111,11 @@ void main() {
|
||||
matching: find.byType(Text),
|
||||
)
|
||||
.first;
|
||||
final Finder hourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourControl',
|
||||
final Finder dialHourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialHourControl',
|
||||
);
|
||||
final Finder minuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MinuteControl',
|
||||
final Finder dialMinuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialMinuteControl',
|
||||
);
|
||||
final Finder dayPeriodControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DayPeriodControl',
|
||||
@ -139,8 +139,8 @@ void main() {
|
||||
useMaterial3: true,
|
||||
);
|
||||
final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
|
||||
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
|
||||
final double hourLeftOffset = tester.getTopLeft(dialHourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(dialMinuteControlFinder).dx;
|
||||
final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
|
||||
|
||||
if (locale == const Locale('en', 'US')) {
|
||||
@ -196,11 +196,11 @@ void main() {
|
||||
matching: find.byType(Text),
|
||||
)
|
||||
.first;
|
||||
final Finder hourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourControl',
|
||||
final Finder dialHourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialHourControl',
|
||||
);
|
||||
final Finder minuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MinuteControl',
|
||||
final Finder dialMinuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialMinuteControl',
|
||||
);
|
||||
final Finder dayPeriodControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DayPeriodControl',
|
||||
@ -224,9 +224,9 @@ void main() {
|
||||
useMaterial3: false,
|
||||
);
|
||||
final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
|
||||
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
|
||||
final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy;
|
||||
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
|
||||
final double hourLeftOffset = tester.getTopLeft(dialHourControlFinder).dx;
|
||||
final double hourTopOffset = tester.getTopLeft(dialHourControlFinder).dy;
|
||||
final double minuteLeftOffset = tester.getTopLeft(dialMinuteControlFinder).dx;
|
||||
final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
|
||||
|
||||
if (locale == const Locale('en', 'US')) {
|
||||
@ -286,11 +286,11 @@ void main() {
|
||||
matching: find.byType(Text),
|
||||
)
|
||||
.first;
|
||||
final Finder hourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourControl',
|
||||
final Finder dialHourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialHourControl',
|
||||
);
|
||||
final Finder minuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MinuteControl',
|
||||
final Finder dialMinuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DialMinuteControl',
|
||||
);
|
||||
final Finder dayPeriodControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_DayPeriodControl',
|
||||
@ -314,9 +314,9 @@ void main() {
|
||||
useMaterial3: true,
|
||||
);
|
||||
final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
|
||||
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
|
||||
final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy;
|
||||
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
|
||||
final double hourLeftOffset = tester.getTopLeft(dialHourControlFinder).dx;
|
||||
final double hourTopOffset = tester.getTopLeft(dialHourControlFinder).dy;
|
||||
final double minuteLeftOffset = tester.getTopLeft(dialMinuteControlFinder).dx;
|
||||
final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
|
||||
|
||||
if (locale == const Locale('en', 'US')) {
|
||||
@ -365,10 +365,10 @@ void main() {
|
||||
testWidgets('Material2 - can localize input mode in all known formats', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
final Finder hourControlFinder = find.byWidgetPredicate(
|
||||
final Finder inputHourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourTextField',
|
||||
);
|
||||
final Finder minuteControlFinder = find.byWidgetPredicate(
|
||||
final Finder inputMinuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MinuteTextField',
|
||||
);
|
||||
final Finder dayPeriodControlFinder = find.byWidgetPredicate(
|
||||
@ -404,8 +404,8 @@ void main() {
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
|
||||
final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
|
||||
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
|
||||
final double hourLeftOffset = tester.getTopLeft(inputHourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(inputMinuteControlFinder).dx;
|
||||
final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
|
||||
|
||||
if (locale == const Locale('en', 'US')) {
|
||||
@ -450,10 +450,10 @@ void main() {
|
||||
testWidgets('Material3 - can localize input mode in all known formats', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
final Finder hourControlFinder = find.byWidgetPredicate(
|
||||
final Finder inputHourControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_HourTextField',
|
||||
);
|
||||
final Finder minuteControlFinder = find.byWidgetPredicate(
|
||||
final Finder inputMinuteControlFinder = find.byWidgetPredicate(
|
||||
(Widget w) => '${w.runtimeType}' == '_MinuteTextField',
|
||||
);
|
||||
final Finder dayPeriodControlFinder = find.byWidgetPredicate(
|
||||
@ -489,8 +489,8 @@ void main() {
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
|
||||
final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
|
||||
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
|
||||
final double hourLeftOffset = tester.getTopLeft(inputHourControlFinder).dx;
|
||||
final double minuteLeftOffset = tester.getTopLeft(inputMinuteControlFinder).dx;
|
||||
final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
|
||||
|
||||
if (locale == const Locale('en', 'US')) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user