Add builder parameter to showDatePicker, showTimePicker (#27703)
This commit is contained in:
parent
1e5d2e55fc
commit
5ee5766c89
@ -25,6 +25,9 @@ import 'material_localizations.dart';
|
||||
import 'text_theme.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
// Examples can assume:
|
||||
// BuildContext context;
|
||||
|
||||
/// Initial display mode of the date picker dialog.
|
||||
///
|
||||
/// Date picker UI mode for either showing a list of available years or a
|
||||
@ -1111,6 +1114,28 @@ typedef SelectableDayPredicate = bool Function(DateTime day);
|
||||
/// The [context] argument is passed to [showDialog], the documentation for
|
||||
/// which discusses how it is used.
|
||||
///
|
||||
/// The [builder] parameter can be used to wrap the dialog widget
|
||||
/// to add inherited widgets like [Theme].
|
||||
///
|
||||
/// {@tool sample}
|
||||
/// Show a date picker with the dark theme.
|
||||
///
|
||||
/// ```dart
|
||||
/// Future<DateTime> selectedDate = showDatePicker(
|
||||
/// context: context,
|
||||
/// initialDate: DateTime.now(),
|
||||
/// firstDate: DateTime(2018),
|
||||
/// lastDate: DateTime(2030),
|
||||
/// builder: (BuildContext context, Widget child) {
|
||||
/// return Theme(
|
||||
/// data: ThemeData.dark(),
|
||||
/// child: child,
|
||||
/// );
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// The [context], [initialDate], [firstDate], and [lastDate] parameters must
|
||||
/// not be null.
|
||||
///
|
||||
@ -1133,6 +1158,7 @@ Future<DateTime> showDatePicker({
|
||||
DatePickerMode initialDatePickerMode = DatePickerMode.day,
|
||||
Locale locale,
|
||||
TextDirection textDirection,
|
||||
TransitionBuilder builder,
|
||||
}) async {
|
||||
assert(initialDate != null);
|
||||
assert(firstDate != null);
|
||||
@ -1173,6 +1199,8 @@ Future<DateTime> showDatePicker({
|
||||
|
||||
return await showDialog<DateTime>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => child,
|
||||
builder: (BuildContext context) {
|
||||
return builder == null ? child : builder(context, child);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ import 'theme.dart';
|
||||
import 'theme_data.dart';
|
||||
import 'time.dart';
|
||||
|
||||
// Examples can assume:
|
||||
// BuildContext context;
|
||||
|
||||
const Duration _kDialAnimateDuration = Duration(milliseconds: 200);
|
||||
const double _kTwoPi = 2 * math.pi;
|
||||
const Duration _kVibrateCommitDelay = Duration(milliseconds: 100);
|
||||
@ -1651,33 +1654,77 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
|
||||
/// The returned Future resolves to the time selected by the user when the user
|
||||
/// closes the dialog. If the user cancels the dialog, null is returned.
|
||||
///
|
||||
/// To show a dialog with [initialTime] equal to the current time:
|
||||
/// {@tool sample}
|
||||
/// Show a dialog with [initialTime] equal to the current time.
|
||||
///
|
||||
/// ```dart
|
||||
/// showTimePicker(
|
||||
/// Future<TimeOfDay> selectedTime = showTimePicker(
|
||||
/// initialTime: TimeOfDay.now(),
|
||||
/// context: context,
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// The `context` argument is passed to [showDialog], the documentation for
|
||||
/// The [context] argument is passed to [showDialog], the documentation for
|
||||
/// which discusses how it is used.
|
||||
///
|
||||
/// The [builder] parameter can be used to wrap the dialog widget
|
||||
/// to add inherited widgets like [Localizations.override],
|
||||
/// [Directionality], or [MediaQuery].
|
||||
///
|
||||
/// {@tool sample}
|
||||
/// Show a dialog with the text direction overridden to be [TextDirection.rtl].
|
||||
///
|
||||
/// ```dart
|
||||
/// Future<TimeOfDay> selectedTimeRTL = showTimePicker(
|
||||
/// context: context,
|
||||
/// initialTime: TimeOfDay.now(),
|
||||
/// builder: (BuildContext context, Widget child) {
|
||||
/// return Directionality(
|
||||
/// textDirection: TextDirection.rtl,
|
||||
/// child: child,
|
||||
/// );
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool sample}
|
||||
/// Show a dialog with time unconditionally displayed in 24 hour format.
|
||||
///
|
||||
/// ```dart
|
||||
/// Future<TimeOfDay> selectedTime24Hour = showTimePicker(
|
||||
/// context: context,
|
||||
/// initialTime: TimeOfDay(hour: 10, minute: 47),
|
||||
/// builder: (BuildContext context, Widget child) {
|
||||
/// return MediaQuery(
|
||||
/// data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
|
||||
/// child: child,
|
||||
/// );
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [showDatePicker], which shows a dialog that contains a material design
|
||||
/// date picker.
|
||||
Future<TimeOfDay> showTimePicker({
|
||||
@required BuildContext context,
|
||||
@required TimeOfDay initialTime
|
||||
@required TimeOfDay initialTime,
|
||||
TransitionBuilder builder,
|
||||
}) async {
|
||||
assert(context != null);
|
||||
assert(initialTime != null);
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
|
||||
final Widget dialog = _TimePickerDialog(initialTime: initialTime);
|
||||
return await showDialog<TimeOfDay>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => _TimePickerDialog(initialTime: initialTime),
|
||||
builder: (BuildContext context) {
|
||||
return builder == null ? dialog : builder(context, dialog);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -723,4 +723,54 @@ void _tests() {
|
||||
expect(renderer.opacity.status, equals(AnimationStatus.dismissed));
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('builder parameter', (WidgetTester tester) async {
|
||||
Widget buildFrame(TextDirection textDirection) {
|
||||
return MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return RaisedButton(
|
||||
child: const Text('X'),
|
||||
onPressed: () {
|
||||
showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2018),
|
||||
lastDate: DateTime(2030),
|
||||
builder: (BuildContext context, Widget child) {
|
||||
return Directionality(
|
||||
textDirection: textDirection,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(TextDirection.ltr));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pumpAndSettle();
|
||||
final double ltrOkRight = tester.getBottomRight(find.text('OK')).dx;
|
||||
|
||||
await tester.tap(find.text('OK')); // dismiss the dialog
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.pumpWidget(buildFrame(TextDirection.rtl));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that the time picker is being laid out RTL.
|
||||
// We expect the left edge of the 'OK' button in the RTL
|
||||
// layout to match the gap between right edge of the 'OK'
|
||||
// button and the right edge of the 800 wide window.
|
||||
expect(tester.getBottomLeft(find.text('OK')).dx, 800 - ltrOkRight);
|
||||
});
|
||||
}
|
||||
|
@ -505,6 +505,54 @@ void _tests() {
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('builder parameter', (WidgetTester tester) async {
|
||||
Widget buildFrame(TextDirection textDirection) {
|
||||
return MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return RaisedButton(
|
||||
child: const Text('X'),
|
||||
onPressed: () {
|
||||
showTimePicker(
|
||||
context: context,
|
||||
initialTime: const TimeOfDay(hour: 7, minute: 0),
|
||||
builder: (BuildContext context, Widget child) {
|
||||
return Directionality(
|
||||
textDirection: textDirection,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame(TextDirection.ltr));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pumpAndSettle();
|
||||
final double ltrOkRight = tester.getBottomRight(find.text('OK')).dx;
|
||||
|
||||
await tester.tap(find.text('OK')); // dismiss the dialog
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.pumpWidget(buildFrame(TextDirection.rtl));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that the time picker is being laid out RTL.
|
||||
// We expect the left edge of the 'OK' button in the RTL
|
||||
// layout to match the gap between right edge of the 'OK'
|
||||
// button and the right edge of the 800 wide window.
|
||||
expect(tester.getBottomLeft(find.text('OK')).dx, 800 - ltrOkRight);
|
||||
});
|
||||
}
|
||||
|
||||
final Finder findDialPaint = find.descendant(
|
||||
|
Loading…
x
Reference in New Issue
Block a user