Unverified Commit 9d41ddcb authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate some material files to nullsafety (#66985)

* migrate some material files to nullsafety

* fix test_private

* address review comments

* fix private test on windows

* use uri in include entry of analysis_options
parent d3155658
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// Flutter widgets implementing Material Design animated icons.
library material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
part of material_animated_icons;
// The code for drawing animated icons is kept in a private API, as we are not
......@@ -38,9 +36,9 @@ class AnimatedIcon extends StatelessWidget {
/// The [progress] and [icon] arguments must not be null.
/// The [size] and [color] default to the value given by the current [IconTheme].
const AnimatedIcon({
Key key,
@required this.icon,
@required this.progress,
Key? key,
required this.icon,
required this.progress,
this.color,
this.size,
this.semanticLabel,
......@@ -71,14 +69,14 @@ class AnimatedIcon extends StatelessWidget {
///
/// See [Theme] to set the current theme and [ThemeData.brightness]
/// for setting the current theme's brightness.
final Color color;
final Color? color;
/// The size of the icon in logical pixels.
///
/// Icons occupy a square with width and height equal to size.
///
/// Defaults to the current [IconTheme] size.
final double size;
final double? size;
/// The icon to display. Available icons are listed in [AnimatedIcons].
final AnimatedIconData icon;
......@@ -92,7 +90,7 @@ class AnimatedIcon extends StatelessWidget {
///
/// * [SemanticsProperties.label], which is set to [semanticLabel] in the
/// underlying [Semantics] widget.
final String semanticLabel;
final String? semanticLabel;
/// The text direction to use for rendering the icon.
///
......@@ -100,18 +98,20 @@ class AnimatedIcon extends StatelessWidget {
///
/// If the text direction is [TextDirection.rtl], the icon will be mirrored
/// horizontally (e.g back arrow will point right).
final TextDirection textDirection;
final TextDirection? textDirection;
static final _UiPathFactory _pathFactory = () => ui.Path();
@override
Widget build(BuildContext context) {
assert(debugCheckHasDirectionality(context));
final _AnimatedIconData iconData = icon as _AnimatedIconData;
final IconThemeData iconTheme = IconTheme.of(context);
final double iconSize = size ?? iconTheme.size;
final TextDirection textDirection = this.textDirection ?? Directionality.of(context);
final double iconOpacity = iconTheme.opacity;
Color iconColor = color ?? iconTheme.color;
assert(iconTheme.isConcrete);
final double iconSize = size ?? iconTheme.size!;
final TextDirection textDirection = this.textDirection ?? Directionality.of(context)!;
final double iconOpacity = iconTheme.opacity!;
Color iconColor = color ?? iconTheme.color!;
if (iconOpacity != 1.0)
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
return Semantics(
......@@ -135,12 +135,12 @@ typedef _UiPathFactory = ui.Path Function();
class _AnimatedIconPainter extends CustomPainter {
_AnimatedIconPainter({
@required this.paths,
@required this.progress,
@required this.color,
@required this.scale,
@required this.shouldMirror,
@required this.uiPathFactory,
required this.paths,
required this.progress,
required this.color,
required this.scale,
required this.shouldMirror,
required this.uiPathFactory,
}) : super(repaint: progress);
// This list is assumed to be immutable, changes to the contents of the list
......@@ -163,7 +163,7 @@ class _AnimatedIconPainter extends CustomPainter {
canvas.translate(-size.width, -size.height);
}
final double clampedProgress = progress.value.clamp(0.0, 1.0) as double;
final double clampedProgress = progress.value.clamp(0.0, 1.0);
for (final _PathFrames path in paths)
path.paint(canvas, color, uiPathFactory, clampedProgress);
}
......@@ -181,26 +181,26 @@ class _AnimatedIconPainter extends CustomPainter {
}
@override
bool hitTest(Offset position) => null;
bool? hitTest(Offset position) => null;
@override
bool shouldRebuildSemantics(CustomPainter oldDelegate) => false;
@override
SemanticsBuilderCallback get semanticsBuilder => null;
SemanticsBuilderCallback? get semanticsBuilder => null;
}
class _PathFrames {
const _PathFrames({
@required this.commands,
@required this.opacities,
required this.commands,
required this.opacities,
});
final List<_PathCommand> commands;
final List<double> opacities;
void paint(ui.Canvas canvas, Color color, _UiPathFactory uiPathFactory, double progress) {
final double opacity = _interpolate<double>(opacities, progress, lerpDouble);
final double opacity = _interpolate<double?>(opacities, progress, lerpDouble)!;
final ui.Paint paint = ui.Paint()
..style = PaintingStyle.fill
..color = color.withOpacity(color.opacity * opacity);
......@@ -232,7 +232,7 @@ class _PathMoveTo extends _PathCommand {
@override
void apply(Path path, double progress) {
final Offset offset = _interpolate<Offset>(points, progress, Offset.lerp);
final Offset offset = _interpolate<Offset?>(points, progress, Offset.lerp)!;
path.moveTo(offset.dx, offset.dy);
}
}
......@@ -246,9 +246,9 @@ class _PathCubicTo extends _PathCommand {
@override
void apply(Path path, double progress) {
final Offset controlPoint1 = _interpolate<Offset>(controlPoints1, progress, Offset.lerp);
final Offset controlPoint2 = _interpolate<Offset>(controlPoints2, progress, Offset.lerp);
final Offset targetPoint = _interpolate<Offset>(targetPoints, progress, Offset.lerp);
final Offset controlPoint1 = _interpolate<Offset?>(controlPoints1, progress, Offset.lerp)!;
final Offset controlPoint2 = _interpolate<Offset?>(controlPoints2, progress, Offset.lerp)!;
final Offset targetPoint = _interpolate<Offset?>(targetPoints, progress, Offset.lerp)!;
path.cubicTo(
controlPoint1.dx, controlPoint1.dy,
controlPoint2.dx, controlPoint2.dy,
......@@ -265,7 +265,7 @@ class _PathLineTo extends _PathCommand {
@override
void apply(Path path, double progress) {
final Offset point = _interpolate<Offset>(points, progress, Offset.lerp);
final Offset point = _interpolate<Offset?>(points, progress, Offset.lerp)!;
path.lineTo(point.dx, point.dy);
}
}
......@@ -295,7 +295,7 @@ T _interpolate<T>(List<T> values, double progress, _Interpolator<T> interpolator
assert(progress >= 0.0);
if (values.length == 1)
return values[0];
final double targetIdx = lerpDouble(0, values.length -1, progress);
final double targetIdx = lerpDouble(0, values.length -1, progress)!;
final int lowIdx = targetIdx.floor();
final int highIdx = targetIdx.ceil();
final double t = targetIdx - lowIdx;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This file serves as the interface between the public and private APIs for
// animated icons.
// The AnimatedIcons class is public and is used to specify available icons,
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
......@@ -87,12 +85,12 @@ class CalendarDatePicker extends StatefulWidget {
/// If [selectableDayPredicate] is non-null, it must return `true` for the
/// [initialDate].
CalendarDatePicker({
Key key,
@required DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
@required this.onDateChanged,
Key? key,
required DateTime initialDate,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
required this.onDateChanged,
this.onDisplayedMonthChanged,
this.initialCalendarMode = DatePickerMode.day,
this.selectableDayPredicate,
......@@ -119,7 +117,7 @@ class CalendarDatePicker extends StatefulWidget {
'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.'
);
assert(
selectableDayPredicate == null || selectableDayPredicate(this.initialDate),
selectableDayPredicate == null || selectableDayPredicate!(this.initialDate),
'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate.'
);
}
......@@ -140,13 +138,13 @@ class CalendarDatePicker extends StatefulWidget {
final ValueChanged<DateTime> onDateChanged;
/// Called when the user navigates to a new month/year in the picker.
final ValueChanged<DateTime> onDisplayedMonthChanged;
final ValueChanged<DateTime>? onDisplayedMonthChanged;
/// The initial display of the calendar picker.
final DatePickerMode initialCalendarMode;
/// Function to provide full control over which dates in the calendar can be selected.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
@override
_CalendarDatePickerState createState() => _CalendarDatePickerState();
......@@ -154,13 +152,13 @@ class CalendarDatePicker extends StatefulWidget {
class _CalendarDatePickerState extends State<CalendarDatePicker> {
bool _announcedInitialDate = false;
DatePickerMode _mode;
DateTime _currentDisplayedMonthDate;
DateTime _selectedDate;
DatePickerMode? _mode;
DateTime? _currentDisplayedMonthDate;
late DateTime _selectedDate;
final GlobalKey _monthPickerKey = GlobalKey();
final GlobalKey _yearPickerKey = GlobalKey();
MaterialLocalizations _localizations;
TextDirection _textDirection;
late MaterialLocalizations _localizations;
late TextDirection _textDirection;
@override
void initState() {
......@@ -180,8 +178,8 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
assert(debugCheckHasMaterial(context));
assert(debugCheckHasMaterialLocalizations(context));
assert(debugCheckHasDirectionality(context));
_localizations = MaterialLocalizations.of(context);
_textDirection = Directionality.of(context);
_localizations = MaterialLocalizations.of(context)!;
_textDirection = Directionality.of(context)!;
if (!_announcedInitialDate) {
_announcedInitialDate = true;
SemanticsService.announce(
......@@ -198,7 +196,7 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
}
void _vibrate() {
switch (Theme.of(context).platform) {
switch (Theme.of(context)!.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
......@@ -231,9 +229,9 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
void _handleMonthChanged(DateTime date) {
setState(() {
if (_currentDisplayedMonthDate.year != date.year || _currentDisplayedMonthDate.month != date.month) {
if (_currentDisplayedMonthDate!.year != date.year || _currentDisplayedMonthDate!.month != date.month) {
_currentDisplayedMonthDate = DateTime(date.year, date.month);
widget.onDisplayedMonthChanged?.call(_currentDisplayedMonthDate);
widget.onDisplayedMonthChanged?.call(_currentDisplayedMonthDate!);
}
});
}
......@@ -257,13 +255,13 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
_vibrate();
setState(() {
_selectedDate = value;
widget.onDateChanged?.call(_selectedDate);
widget.onDateChanged(_selectedDate);
});
}
Widget _buildPicker() {
assert(_mode != null);
switch (_mode) {
switch (_mode!) {
case DatePickerMode.day:
return _MonthPicker(
key: _monthPickerKey,
......@@ -284,13 +282,12 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
currentDate: widget.currentDate,
firstDate: widget.firstDate,
lastDate: widget.lastDate,
initialDate: _currentDisplayedMonthDate,
initialDate: _currentDisplayedMonthDate!,
selectedDate: _selectedDate,
onChanged: _handleYearChanged,
),
);
}
return null;
}
@override
......@@ -306,8 +303,8 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
),
// Put the mode toggle button on top so that it won't be covered up by the _MonthPicker
_DatePickerModeToggleButton(
mode: _mode,
title: _localizations.formatMonthYear(_currentDisplayedMonthDate),
mode: _mode!,
title: _localizations.formatMonthYear(_currentDisplayedMonthDate!),
onTitlePressed: () {
// Toggle the day/year mode.
_handleModeChanged(_mode == DatePickerMode.day ? DatePickerMode.year : DatePickerMode.day);
......@@ -324,9 +321,9 @@ class _CalendarDatePickerState extends State<CalendarDatePicker> {
/// [DatePickerMode] to display either the calendar view or the year list.
class _DatePickerModeToggleButton extends StatefulWidget {
const _DatePickerModeToggleButton({
@required this.mode,
@required this.title,
@required this.onTitlePressed,
required this.mode,
required this.title,
required this.onTitlePressed,
});
/// The current display of the calendar picker.
......@@ -343,7 +340,7 @@ class _DatePickerModeToggleButton extends StatefulWidget {
}
class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton> with SingleTickerProviderStateMixin {
AnimationController _controller;
late AnimationController _controller;
@override
void initState() {
......@@ -372,8 +369,8 @@ class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton
@override
Widget build(BuildContext context) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
final TextTheme textTheme = Theme.of(context).textTheme;
final ColorScheme colorScheme = Theme.of(context)!.colorScheme;
final TextTheme textTheme = Theme.of(context)!.textTheme;
final Color controlColor = colorScheme.onSurface.withOpacity(0.60);
return Container(
......@@ -383,7 +380,7 @@ class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton
children: <Widget>[
Flexible(
child: Semantics(
label: MaterialLocalizations.of(context).selectYearSemanticsLabel,
label: MaterialLocalizations.of(context)!.selectYearSemanticsLabel,
excludeSemantics: true,
button: true,
child: Container(
......@@ -435,14 +432,14 @@ class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton
class _MonthPicker extends StatefulWidget {
/// Creates a month picker.
_MonthPicker({
Key key,
@required this.initialMonth,
@required this.currentDate,
@required this.firstDate,
@required this.lastDate,
@required this.selectedDate,
@required this.onChanged,
@required this.onDisplayedMonthChanged,
Key? key,
required this.initialMonth,
required this.currentDate,
required this.firstDate,
required this.lastDate,
required this.selectedDate,
required this.onChanged,
required this.onDisplayedMonthChanged,
this.selectableDayPredicate,
}) : assert(selectedDate != null),
assert(currentDate != null),
......@@ -455,7 +452,7 @@ class _MonthPicker extends StatefulWidget {
super(key: key);
/// The initial month to display.
final DateTime initialMonth;
final DateTime? initialMonth;
/// The current date.
///
......@@ -484,7 +481,7 @@ class _MonthPicker extends StatefulWidget {
final ValueChanged<DateTime> onDisplayedMonthChanged;
/// Optional user supplied predicate function to customize selectable days.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
@override
_MonthPickerState createState() => _MonthPickerState();
......@@ -492,24 +489,24 @@ class _MonthPicker extends StatefulWidget {
class _MonthPickerState extends State<_MonthPicker> {
final GlobalKey _pageViewKey = GlobalKey();
DateTime _currentMonth;
DateTime _nextMonthDate;
DateTime _previousMonthDate;
PageController _pageController;
MaterialLocalizations _localizations;
TextDirection _textDirection;
Map<LogicalKeySet, Intent> _shortcutMap;
Map<Type, Action<Intent>> _actionMap;
FocusNode _dayGridFocus;
DateTime _focusedDay;
DateTime? _currentMonth;
late DateTime _nextMonthDate;
late DateTime _previousMonthDate;
PageController? _pageController;
late MaterialLocalizations _localizations;
TextDirection? _textDirection;
Map<LogicalKeySet, Intent>? _shortcutMap;
Map<Type, Action<Intent>>? _actionMap;
FocusNode? _dayGridFocus;
DateTime? _focusedDay;
@override
void initState() {
super.initState();
_currentMonth = widget.initialMonth;
_previousMonthDate = utils.addMonthsToMonthDate(_currentMonth, -1);
_nextMonthDate = utils.addMonthsToMonthDate(_currentMonth, 1);
_pageController = PageController(initialPage: utils.monthDelta(widget.firstDate, _currentMonth));
_previousMonthDate = utils.addMonthsToMonthDate(_currentMonth!, -1);
_nextMonthDate = utils.addMonthsToMonthDate(_currentMonth!, 1);
_pageController = PageController(initialPage: utils.monthDelta(widget.firstDate, _currentMonth!));
_shortcutMap = <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.arrowLeft): const DirectionalFocusIntent(TraversalDirection.left),
LogicalKeySet(LogicalKeyboardKey.arrowRight): const DirectionalFocusIntent(TraversalDirection.right),
......@@ -527,7 +524,7 @@ class _MonthPickerState extends State<_MonthPicker> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
_localizations = MaterialLocalizations.of(context);
_localizations = MaterialLocalizations.of(context)!;
_textDirection = Directionality.of(context);
}
......@@ -535,20 +532,20 @@ class _MonthPickerState extends State<_MonthPicker> {
void didUpdateWidget(_MonthPicker oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.initialMonth != oldWidget.initialMonth) {
_showMonth(widget.initialMonth);
_showMonth(widget.initialMonth!);
}
}
@override
void dispose() {
_pageController?.dispose();
_dayGridFocus.dispose();
_dayGridFocus!.dispose();
super.dispose();
}
void _handleDateSelected(DateTime selectedDate) {
_focusedDay = selectedDate;
widget.onChanged?.call(selectedDate);
widget.onChanged(selectedDate);
}
void _handleMonthPageChanged(int monthPage) {
......@@ -556,14 +553,14 @@ class _MonthPickerState extends State<_MonthPicker> {
final DateTime monthDate = utils.addMonthsToMonthDate(widget.firstDate, monthPage);
if (!utils.isSameMonth(_currentMonth, monthDate)) {
_currentMonth = DateTime(monthDate.year, monthDate.month);
_previousMonthDate = utils.addMonthsToMonthDate(_currentMonth, -1);
_nextMonthDate = utils.addMonthsToMonthDate(_currentMonth, 1);
widget.onDisplayedMonthChanged?.call(_currentMonth);
_previousMonthDate = utils.addMonthsToMonthDate(_currentMonth!, -1);
_nextMonthDate = utils.addMonthsToMonthDate(_currentMonth!, 1);
widget.onDisplayedMonthChanged(_currentMonth!);
if (_focusedDay != null && !utils.isSameMonth(_focusedDay, _currentMonth)) {
// We have navigated to a new month with the grid focused, but the
// focused day is not in this month. Choose a new one trying to keep
// the same day of the month.
_focusedDay = _focusableDayForMonth(_currentMonth, _focusedDay.day);
_focusedDay = _focusableDayForMonth(_currentMonth!, _focusedDay!.day);
}
}
});
......@@ -574,7 +571,7 @@ class _MonthPickerState extends State<_MonthPicker> {
/// If the preferredDay is available in the month it will be returned,
/// otherwise the first selectable day in the month will be returned. If
/// no dates are selectable in the month, then it will return null.
DateTime _focusableDayForMonth(DateTime month, int preferredDay) {
DateTime? _focusableDayForMonth(DateTime month, int preferredDay) {
final int daysInMonth = utils.getDaysInMonth(month.year, month.month);
// Can we use the preferred day in this month?
......@@ -598,9 +595,9 @@ class _MonthPickerState extends State<_MonthPicker> {
if (!_isDisplayingLastMonth) {
SemanticsService.announce(
_localizations.formatMonthYear(_nextMonthDate),
_textDirection,
_textDirection!,
);
_pageController.nextPage(
_pageController!.nextPage(
duration: _monthScrollDuration,
curve: Curves.ease,
);
......@@ -612,9 +609,9 @@ class _MonthPickerState extends State<_MonthPicker> {
if (!_isDisplayingFirstMonth) {
SemanticsService.announce(
_localizations.formatMonthYear(_previousMonthDate),
_textDirection,
_textDirection!,
);
_pageController.previousPage(
_pageController!.previousPage(
duration: _monthScrollDuration,
curve: Curves.ease,
);
......@@ -624,7 +621,7 @@ class _MonthPickerState extends State<_MonthPicker> {
/// Navigate to the given month.
void _showMonth(DateTime month) {
final int monthPage = utils.monthDelta(widget.firstDate, month);
_pageController.animateToPage(monthPage,
_pageController!.animateToPage(monthPage,
duration: _monthScrollDuration,
curve: Curves.ease
);
......@@ -632,14 +629,14 @@ class _MonthPickerState extends State<_MonthPicker> {
/// True if the earliest allowable month is displayed.
bool get _isDisplayingFirstMonth {
return !_currentMonth.isAfter(
return !_currentMonth!.isAfter(
DateTime(widget.firstDate.year, widget.firstDate.month),
);
}
/// True if the latest allowable month is displayed.
bool get _isDisplayingLastMonth {
return !_currentMonth.isBefore(
return !_currentMonth!.isBefore(
DateTime(widget.lastDate.year, widget.lastDate.month),
);
}
......@@ -651,9 +648,9 @@ class _MonthPickerState extends State<_MonthPicker> {
if (utils.isSameMonth(widget.selectedDate, _currentMonth)) {
_focusedDay = widget.selectedDate;
} else if (utils.isSameMonth(widget.currentDate, _currentMonth)) {
_focusedDay = _focusableDayForMonth(_currentMonth, widget.currentDate.day);
_focusedDay = _focusableDayForMonth(_currentMonth!, widget.currentDate.day);
} else {
_focusedDay = _focusableDayForMonth(_currentMonth, 1);
_focusedDay = _focusableDayForMonth(_currentMonth!, 1);
}
}
});
......@@ -661,14 +658,14 @@ class _MonthPickerState extends State<_MonthPicker> {
/// Move focus to the next element after the day grid.
void _handleGridNextFocus(NextFocusIntent intent) {
_dayGridFocus.requestFocus();
_dayGridFocus.nextFocus();
_dayGridFocus!.requestFocus();
_dayGridFocus!.nextFocus();
}
/// Move focus to the previous element before the day grid.
void _handleGridPreviousFocus(PreviousFocusIntent intent) {
_dayGridFocus.requestFocus();
_dayGridFocus.previousFocus();
_dayGridFocus!.requestFocus();
_dayGridFocus!.previousFocus();
}
/// Move the internal focus date in the direction of the given intent.
......@@ -683,11 +680,11 @@ class _MonthPickerState extends State<_MonthPicker> {
void _handleDirectionFocus(DirectionalFocusIntent intent) {
assert(_focusedDay != null);
setState(() {
final DateTime nextDate = _nextDateInDirection(_focusedDay, intent.direction);
final DateTime? nextDate = _nextDateInDirection(_focusedDay!, intent.direction);
if (nextDate != null) {
_focusedDay = nextDate;
if (!utils.isSameMonth(_focusedDay, _currentMonth)) {
_showMonth(_focusedDay);
_showMonth(_focusedDay!);
}
}
});
......@@ -708,11 +705,11 @@ class _MonthPickerState extends State<_MonthPicker> {
else if (traversalDirection == TraversalDirection.right)
traversalDirection = TraversalDirection.left;
}
return _directionOffset[traversalDirection];
return _directionOffset[traversalDirection]!;
}
DateTime _nextDateInDirection(DateTime date, TraversalDirection direction) {
final TextDirection textDirection = Directionality.of(context);
DateTime? _nextDateInDirection(DateTime date, TraversalDirection direction) {
final TextDirection textDirection = Directionality.of(context)!;
DateTime nextDate = utils.addDaysToDate(date, _dayDirectionOffset(direction, textDirection));
while (!nextDate.isBefore(widget.firstDate) && !nextDate.isAfter(widget.lastDate)) {
if (_isSelectable(nextDate)) {
......@@ -724,7 +721,7 @@ class _MonthPickerState extends State<_MonthPicker> {
}
bool _isSelectable(DateTime date) {
return widget.selectableDayPredicate == null || widget.selectableDayPredicate.call(date);
return widget.selectableDayPredicate == null || widget.selectableDayPredicate!.call(date);
}
Widget _buildItems(BuildContext context, int index) {
......@@ -745,7 +742,7 @@ class _MonthPickerState extends State<_MonthPicker> {
Widget build(BuildContext context) {
final String previousTooltipText = '${_localizations.previousMonthTooltip} ${_localizations.formatMonthYear(_previousMonthDate)}';
final String nextTooltipText = '${_localizations.nextMonthTooltip} ${_localizations.formatMonthYear(_nextMonthDate)}';
final Color controlColor = Theme.of(context).colorScheme.onSurface.withOpacity(0.60);
final Color controlColor = Theme.of(context)!.colorScheme.onSurface.withOpacity(0.60);
return Semantics(
child: Column(
......@@ -778,7 +775,7 @@ class _MonthPickerState extends State<_MonthPicker> {
focusNode: _dayGridFocus,
onFocusChange: _handleGridFocusChange,
child: _FocusedDate(
date: _dayGridFocus.hasFocus ? _focusedDay : null,
date: _dayGridFocus!.hasFocus ? _focusedDay : null,
child: PageView.builder(
key: _pageViewKey,
controller: _pageController,
......@@ -802,20 +799,20 @@ class _MonthPickerState extends State<_MonthPicker> {
/// what the currently focused date (if any) should be.
class _FocusedDate extends InheritedWidget {
const _FocusedDate({
Key key,
Widget child,
Key? key,
required Widget child,
this.date
}) : super(key: key, child: child);
final DateTime date;
final DateTime? date;
@override
bool updateShouldNotify(_FocusedDate oldWidget) {
return !utils.isSameDay(date, oldWidget.date);
}
static DateTime of(BuildContext context) {
final _FocusedDate focusedDate = context.dependOnInheritedWidgetOfExactType<_FocusedDate>();
static DateTime? of(BuildContext context) {
final _FocusedDate? focusedDate = context.dependOnInheritedWidgetOfExactType<_FocusedDate>();
return focusedDate?.date;
}
}
......@@ -827,13 +824,13 @@ class _FocusedDate extends InheritedWidget {
class _DayPicker extends StatefulWidget {
/// Creates a day picker.
_DayPicker({
Key key,
@required this.currentDate,
@required this.displayedMonth,
@required this.firstDate,
@required this.lastDate,
@required this.selectedDate,
@required this.onChanged,
Key? key,
required this.currentDate,
required this.displayedMonth,
required this.firstDate,
required this.lastDate,
required this.selectedDate,
required this.onChanged,
this.selectableDayPredicate,
}) : assert(currentDate != null),
assert(displayedMonth != null),
......@@ -871,7 +868,7 @@ class _DayPicker extends StatefulWidget {
final DateTime displayedMonth;
/// Optional user supplied predicate function to customize selectable days.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
@override
_DayPickerState createState() => _DayPickerState();
......@@ -880,7 +877,7 @@ class _DayPicker extends StatefulWidget {
class _DayPickerState extends State<_DayPicker> {
/// List of [FocusNode]s, one for each day of the month.
List<FocusNode> _dayFocusNodes;
late List<FocusNode> _dayFocusNodes;
@override
void initState() {
......@@ -896,7 +893,7 @@ class _DayPickerState extends State<_DayPicker> {
void didChangeDependencies() {
super.didChangeDependencies();
// Check to see if the focused date is in this month, if so focus it.
final DateTime focusedDate = _FocusedDate.of(context);
final DateTime? focusedDate = _FocusedDate.of(context);
if (focusedDate != null && utils.isSameMonth(widget.displayedMonth, focusedDate)) {
_dayFocusNodes[focusedDate.day - 1].requestFocus();
}
......@@ -928,7 +925,7 @@ class _DayPickerState extends State<_DayPicker> {
/// _ _ _ _ 1 2 3
/// 4 5 6 7 8 9 10
/// ```
List<Widget> _dayHeaders(TextStyle headerStyle, MaterialLocalizations localizations) {
List<Widget> _dayHeaders(TextStyle? headerStyle, MaterialLocalizations localizations) {
final List<Widget> result = <Widget>[];
for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) {
final String weekday = localizations.narrowWeekdays[i];
......@@ -943,13 +940,13 @@ class _DayPickerState extends State<_DayPicker> {
@override
Widget build(BuildContext context) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final TextTheme textTheme = Theme.of(context).textTheme;
final TextStyle headerStyle = textTheme.caption?.apply(
final ColorScheme colorScheme = Theme.of(context)!.colorScheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final TextTheme textTheme = Theme.of(context)!.textTheme;
final TextStyle? headerStyle = textTheme.caption?.apply(
color: colorScheme.onSurface.withOpacity(0.60),
);
final TextStyle dayStyle = textTheme.caption;
final TextStyle dayStyle = textTheme.caption!;
final Color enabledDayColor = colorScheme.onSurface.withOpacity(0.87);
final Color disabledDayColor = colorScheme.onSurface.withOpacity(0.38);
final Color selectedDayColor = colorScheme.onPrimary;
......@@ -974,11 +971,11 @@ class _DayPickerState extends State<_DayPicker> {
final DateTime dayToBuild = DateTime(year, month, day);
final bool isDisabled = dayToBuild.isAfter(widget.lastDate) ||
dayToBuild.isBefore(widget.firstDate) ||
(widget.selectableDayPredicate != null && !widget.selectableDayPredicate(dayToBuild));
(widget.selectableDayPredicate != null && !widget.selectableDayPredicate!(dayToBuild));
final bool isSelectedDay = utils.isSameDay(widget.selectedDate, dayToBuild);
final bool isToday = utils.isSameDay(widget.currentDate, dayToBuild);
BoxDecoration decoration;
BoxDecoration? decoration;
Color dayColor = enabledDayColor;
if (isSelectedDay) {
// The selected day gets a circle background highlight, and a
......@@ -1084,13 +1081,13 @@ class _YearPicker extends StatefulWidget {
/// The [currentDate, [firstDate], [lastDate], [selectedDate], and [onChanged]
/// arguments must be non-null. The [lastDate] must be after the [firstDate].
_YearPicker({
Key key,
@required this.currentDate,
@required this.firstDate,
@required this.lastDate,
@required this.initialDate,
@required this.selectedDate,
@required this.onChanged,
Key? key,
required this.currentDate,
required this.firstDate,
required this.lastDate,
required this.initialDate,
required this.selectedDate,
required this.onChanged,
}) : assert(currentDate != null),
assert(firstDate != null),
assert(lastDate != null),
......@@ -1127,7 +1124,7 @@ class _YearPicker extends StatefulWidget {
}
class _YearPickerState extends State<_YearPicker> {
ScrollController scrollController;
late ScrollController scrollController;
// The approximate number of years necessary to fill the available space.
static const int minYears = 18;
......@@ -1146,8 +1143,8 @@ class _YearPickerState extends State<_YearPicker> {
}
Widget _buildYearItem(BuildContext context, int index) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
final TextTheme textTheme = Theme.of(context).textTheme;
final ColorScheme colorScheme = Theme.of(context)!.colorScheme;
final TextTheme textTheme = Theme.of(context)!.textTheme;
// Backfill the _YearPicker with disabled years if necessary.
final int offset = _itemCount < minYears ? (minYears - _itemCount) ~/ 2 : 0;
......@@ -1168,9 +1165,9 @@ class _YearPickerState extends State<_YearPicker> {
} else {
textColor = colorScheme.onSurface.withOpacity(0.87);
}
final TextStyle itemStyle = textTheme.bodyText1?.apply(color: textColor);
final TextStyle? itemStyle = textTheme.bodyText1?.apply(color: textColor);
BoxDecoration decoration;
BoxDecoration? decoration;
if (isSelected) {
decoration = BoxDecoration(
color: colorScheme.primary,
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'package:flutter/gestures.dart' show DragStartBehavior;
......@@ -17,7 +15,6 @@ import '../ink_well.dart';
import '../material_localizations.dart';
import '../text_theme.dart';
import '../theme.dart';
import 'date_utils.dart' as utils;
const Duration _monthScrollDuration = Duration(milliseconds: 200);
......@@ -38,14 +35,14 @@ const double _maxCalendarWidthPortrait = 480.0;
class CalendarDateRangePicker extends StatefulWidget {
/// Creates a scrollable calendar grid for picking date ranges.
CalendarDateRangePicker({
Key key,
DateTime initialStartDate,
DateTime initialEndDate,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
@required this.onStartDateChanged,
@required this.onEndDateChanged,
Key? key,
DateTime? initialStartDate,
DateTime? initialEndDate,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
required this.onStartDateChanged,
required this.onEndDateChanged,
}) : initialStartDate = initialStartDate != null ? utils.dateOnly(initialStartDate) : null,
initialEndDate = initialEndDate != null ? utils.dateOnly(initialEndDate) : null,
assert(firstDate != null),
......@@ -55,7 +52,7 @@ class CalendarDateRangePicker extends StatefulWidget {
currentDate = utils.dateOnly(currentDate ?? DateTime.now()),
super(key: key) {
assert(
this.initialStartDate == null || this.initialEndDate == null || !this.initialStartDate.isAfter(initialEndDate),
this.initialStartDate == null || this.initialEndDate == null || !this.initialStartDate!.isAfter(initialEndDate!),
'initialStartDate must be on or before initialEndDate.'
);
assert(
......@@ -65,10 +62,10 @@ class CalendarDateRangePicker extends StatefulWidget {
}
/// The [DateTime] that represents the start of the initial date range selection.
final DateTime initialStartDate;
final DateTime? initialStartDate;
/// The [DateTime] that represents the end of the initial date range selection.
final DateTime initialEndDate;
final DateTime? initialEndDate;
/// The earliest allowable [DateTime] that the user can select.
final DateTime firstDate;
......@@ -80,10 +77,10 @@ class CalendarDateRangePicker extends StatefulWidget {
final DateTime currentDate;
/// Called when the user changes the start date of the selected range.
final ValueChanged<DateTime> onStartDateChanged;
final ValueChanged<DateTime>? onStartDateChanged;
/// Called when the user changes the end date of the selected range.
final ValueChanged<DateTime> onEndDateChanged;
final ValueChanged<DateTime?>? onEndDateChanged;
@override
_CalendarDateRangePickerState createState() => _CalendarDateRangePickerState();
......@@ -91,11 +88,11 @@ class CalendarDateRangePicker extends StatefulWidget {
class _CalendarDateRangePickerState extends State<CalendarDateRangePicker> {
final GlobalKey _scrollViewKey = GlobalKey();
DateTime _startDate;
DateTime _endDate;
DateTime? _startDate;
DateTime? _endDate;
int _initialMonthIndex = 0;
ScrollController _controller;
bool _showWeekBottomDivider;
late ScrollController _controller;
late bool _showWeekBottomDivider;
@override
void initState() {
......@@ -138,7 +135,7 @@ class _CalendarDateRangePickerState extends State<CalendarDateRangePicker> {
int get _numberOfMonths => utils.monthDelta(widget.firstDate, widget.lastDate) + 1;
void _vibrate() {
switch (Theme.of(context).platform) {
switch (Theme.of(context)!.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
HapticFeedback.vibrate();
......@@ -160,12 +157,12 @@ class _CalendarDateRangePickerState extends State<CalendarDateRangePicker> {
void _updateSelection(DateTime date) {
_vibrate();
setState(() {
if (_startDate != null && _endDate == null && !date.isBefore(_startDate)) {
if (_startDate != null && _endDate == null && !date.isBefore(_startDate!)) {
_endDate = date;
widget.onEndDateChanged?.call(_endDate);
} else {
_startDate = date;
widget.onStartDateChanged?.call(_startDate);
widget.onStartDateChanged?.call(_startDate!);
if (_endDate != null) {
_endDate = null;
widget.onEndDateChanged?.call(_endDate);
......@@ -236,11 +233,11 @@ class _CalendarDateRangePickerState extends State<CalendarDateRangePicker> {
class _CalendarKeyboardNavigator extends StatefulWidget {
const _CalendarKeyboardNavigator({
Key key,
@required this.child,
@required this.firstDate,
@required this.lastDate,
@required this.initialFocusedDay,
Key? key,
required this.child,
required this.firstDate,
required this.lastDate,
required this.initialFocusedDay,
}) : super(key: key);
final Widget child;
......@@ -254,11 +251,11 @@ class _CalendarKeyboardNavigator extends StatefulWidget {
class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator> {
Map<LogicalKeySet, Intent> _shortcutMap;
Map<Type, Action<Intent>> _actionMap;
FocusNode _dayGridFocus;
TraversalDirection _dayTraversalDirection;
DateTime _focusedDay;
late Map<LogicalKeySet, Intent> _shortcutMap;
late Map<Type, Action<Intent>> _actionMap;
late FocusNode _dayGridFocus;
TraversalDirection? _dayTraversalDirection;
DateTime? _focusedDay;
@override
void initState() {
......@@ -316,7 +313,7 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
void _handleDirectionFocus(DirectionalFocusIntent intent) {
assert(_focusedDay != null);
setState(() {
final DateTime nextDate = _nextDateInDirection(_focusedDay, intent.direction);
final DateTime? nextDate = _nextDateInDirection(_focusedDay!, intent.direction);
if (nextDate != null) {
_focusedDay = nextDate;
_dayTraversalDirection = intent.direction;
......@@ -339,11 +336,11 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
else if (traversalDirection == TraversalDirection.right)
traversalDirection = TraversalDirection.left;
}
return _directionOffset[traversalDirection];
return _directionOffset[traversalDirection]!;
}
DateTime _nextDateInDirection(DateTime date, TraversalDirection direction) {
final TextDirection textDirection = Directionality.of(context);
DateTime? _nextDateInDirection(DateTime date, TraversalDirection direction) {
final TextDirection textDirection = Directionality.of(context)!;
final DateTime nextDate = utils.addDaysToDate(date, _dayDirectionOffset(direction, textDirection));
if (!nextDate.isBefore(widget.firstDate) && !nextDate.isAfter(widget.lastDate)) {
return nextDate;
......@@ -373,21 +370,21 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
/// what the currently focused date (if any) should be.
class _FocusedDate extends InheritedWidget {
const _FocusedDate({
Key key,
Widget child,
Key? key,
required Widget child,
this.date,
this.scrollDirection,
}) : super(key: key, child: child);
final DateTime date;
final TraversalDirection scrollDirection;
final DateTime? date;
final TraversalDirection? scrollDirection;
@override
bool updateShouldNotify(_FocusedDate oldWidget) {
return !utils.isSameDay(date, oldWidget.date) || scrollDirection != oldWidget.scrollDirection;
}
static _FocusedDate of(BuildContext context) {
static _FocusedDate? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<_FocusedDate>();
}
}
......@@ -427,10 +424,10 @@ class _DayHeaders extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final ThemeData themeData = Theme.of(context)!;
final ColorScheme colorScheme = themeData.colorScheme;
final TextStyle textStyle = themeData.textTheme.subtitle2.apply(color: colorScheme.onSurface);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final TextStyle textStyle = themeData.textTheme.subtitle2!.apply(color: colorScheme.onSurface);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final List<Widget> labels = _getDayHeaders(textStyle, localizations);
// Add leading and trailing containers for edges of the custom grid layout.
......@@ -439,7 +436,7 @@ class _DayHeaders extends StatelessWidget {
return Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).orientation == Orientation.landscape
maxWidth: MediaQuery.of(context)!.orientation == Orientation.landscape
? _maxCalendarWidthLandscape
: _maxCalendarWidthPortrait,
maxHeight: _monthItemRowHeight,
......@@ -484,10 +481,10 @@ class _MonthSliverGridLayout extends SliverGridLayout {
/// This is necessary to facilitate the painting of the range highlight
/// correctly.
const _MonthSliverGridLayout({
@required this.crossAxisCount,
@required this.dayChildWidth,
@required this.edgeChildWidth,
@required this.reverseCrossAxis,
required this.crossAxisCount,
required this.dayChildWidth,
required this.edgeChildWidth,
required this.reverseCrossAxis,
}) : assert(crossAxisCount != null && crossAxisCount > 0),
assert(dayChildWidth != null && dayChildWidth >= 0),
assert(edgeChildWidth != null && edgeChildWidth >= 0),
......@@ -575,14 +572,14 @@ class _MonthSliverGridLayout extends SliverGridLayout {
class _MonthItem extends StatefulWidget {
/// Creates a month item.
_MonthItem({
Key key,
@required this.selectedDateStart,
@required this.selectedDateEnd,
@required this.currentDate,
@required this.onChanged,
@required this.firstDate,
@required this.lastDate,
@required this.displayedMonth,
Key? key,
required this.selectedDateStart,
required this.selectedDateEnd,
required this.currentDate,
required this.onChanged,
required this.firstDate,
required this.lastDate,
required this.displayedMonth,
this.dragStartBehavior = DragStartBehavior.start,
}) : assert(firstDate != null),
assert(lastDate != null),
......@@ -601,12 +598,12 @@ class _MonthItem extends StatefulWidget {
/// The currently selected start date.
///
/// This date is highlighted in the picker.
final DateTime selectedDateStart;
final DateTime? selectedDateStart;
/// The currently selected end date.
///
/// This date is highlighted in the picker.
final DateTime selectedDateEnd;
final DateTime? selectedDateEnd;
/// The current date at the time the picker is displayed.
final DateTime currentDate;
......@@ -648,7 +645,7 @@ class _MonthItem extends StatefulWidget {
class _MonthItemState extends State<_MonthItem> {
/// List of [FocusNode]s, one for each day of the month.
List<FocusNode> _dayFocusNodes;
late List<FocusNode> _dayFocusNodes;
@override
void initState() {
......@@ -664,7 +661,7 @@ class _MonthItemState extends State<_MonthItem> {
void didChangeDependencies() {
super.didChangeDependencies();
// Check to see if the focused date is in this month, if so focus it.
final DateTime focusedDate = _FocusedDate.of(context)?.date;
final DateTime? focusedDate = _FocusedDate.of(context)?.date;
if (focusedDate != null && utils.isSameMonth(widget.displayedMonth, focusedDate)) {
_dayFocusNodes[focusedDate.day - 1].requestFocus();
}
......@@ -679,12 +676,12 @@ class _MonthItemState extends State<_MonthItem> {
}
Color _highlightColor(BuildContext context) {
return Theme.of(context).colorScheme.primary.withOpacity(0.12);
return Theme.of(context)!.colorScheme.primary.withOpacity(0.12);
}
void _dayFocusChanged(bool focused) {
if (focused) {
final TraversalDirection focusDirection = _FocusedDate.of(context)?.scrollDirection;
final TraversalDirection? focusDirection = _FocusedDate.of(context)?.scrollDirection;
if (focusDirection != null) {
ScrollPositionAlignmentPolicy policy = ScrollPositionAlignmentPolicy.explicit;
switch (focusDirection) {
......@@ -697,7 +694,7 @@ class _MonthItemState extends State<_MonthItem> {
policy = ScrollPositionAlignmentPolicy.keepVisibleAtEnd;
break;
}
Scrollable.ensureVisible(primaryFocus.context,
Scrollable.ensureVisible(primaryFocus!.context!,
duration: _monthScrollDuration,
alignmentPolicy: policy,
);
......@@ -706,27 +703,27 @@ class _MonthItemState extends State<_MonthItem> {
}
Widget _buildDayItem(BuildContext context, DateTime dayToBuild, int firstDayOffset, int daysInMonth) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final TextTheme textTheme = theme.textTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final TextDirection textDirection = Directionality.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final TextDirection? textDirection = Directionality.of(context);
final Color highlightColor = _highlightColor(context);
final int day = dayToBuild.day;
final bool isDisabled = dayToBuild.isAfter(widget.lastDate) || dayToBuild.isBefore(widget.firstDate);
BoxDecoration decoration;
TextStyle itemStyle = textTheme.bodyText2;
BoxDecoration? decoration;
TextStyle? itemStyle = textTheme.bodyText2;
final bool isRangeSelected = widget.selectedDateStart != null && widget.selectedDateEnd != null;
final bool isSelectedDayStart = widget.selectedDateStart != null && dayToBuild.isAtSameMomentAs(widget.selectedDateStart);
final bool isSelectedDayEnd = widget.selectedDateEnd != null && dayToBuild.isAtSameMomentAs(widget.selectedDateEnd);
final bool isSelectedDayStart = widget.selectedDateStart != null && dayToBuild.isAtSameMomentAs(widget.selectedDateStart!);
final bool isSelectedDayEnd = widget.selectedDateEnd != null && dayToBuild.isAtSameMomentAs(widget.selectedDateEnd!);
final bool isInRange = isRangeSelected &&
dayToBuild.isAfter(widget.selectedDateStart) &&
dayToBuild.isBefore(widget.selectedDateEnd);
dayToBuild.isAfter(widget.selectedDateStart!) &&
dayToBuild.isBefore(widget.selectedDateEnd!);
_HighlightPainter highlightPainter;
_HighlightPainter? highlightPainter;
if (isSelectedDayStart || isSelectedDayEnd) {
// The selected start and end dates gets a circle background
......@@ -819,9 +816,9 @@ class _MonthItemState extends State<_MonthItem> {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final ThemeData themeData = Theme.of(context)!;
final TextTheme textTheme = themeData.textTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final int year = widget.displayedMonth.year;
final int month = widget.displayedMonth.month;
final int daysInMonth = utils.getDaysInMonth(year, month);
......@@ -869,8 +866,8 @@ class _MonthItemState extends State<_MonthItem> {
!(dayOffset > 0 && i == 0) &&
widget.selectedDateStart != null &&
widget.selectedDateEnd != null &&
dateAfterLeadingPadding.isAfter(widget.selectedDateStart) &&
!dateAfterLeadingPadding.isAfter(widget.selectedDateEnd);
dateAfterLeadingPadding.isAfter(widget.selectedDateStart!) &&
!dateAfterLeadingPadding.isAfter(widget.selectedDateEnd!);
weekList.insert(0, _buildEdgeContainer(context, isLeadingInRange));
// Only add a trailing edge container if it is for a full week and not a
......@@ -883,15 +880,15 @@ class _MonthItemState extends State<_MonthItem> {
final bool isTrailingInRange =
widget.selectedDateStart != null &&
widget.selectedDateEnd != null &&
!dateBeforeTrailingPadding.isBefore(widget.selectedDateStart) &&
dateBeforeTrailingPadding.isBefore(widget.selectedDateEnd);
!dateBeforeTrailingPadding.isBefore(widget.selectedDateStart!) &&
dateBeforeTrailingPadding.isBefore(widget.selectedDateEnd!);
weekList.add(_buildEdgeContainer(context, isTrailingInRange));
}
paddedDayItems.addAll(weekList);
}
final double maxWidth = MediaQuery.of(context).orientation == Orientation.landscape
final double maxWidth = MediaQuery.of(context)!.orientation == Orientation.landscape
? _maxCalendarWidthLandscape
: _maxCalendarWidthPortrait;
return Column(
......@@ -904,7 +901,7 @@ class _MonthItemState extends State<_MonthItem> {
child: ExcludeSemantics(
child: Text(
localizations.formatMonthYear(widget.displayedMonth),
style: textTheme.bodyText2.apply(color: themeData.colorScheme.onSurface),
style: textTheme.bodyText2!.apply(color: themeData.colorScheme.onSurface),
),
),
),
......@@ -951,14 +948,14 @@ enum _HighlightPainterStyle {
/// a combination of the [style] and [textDirection].
class _HighlightPainter extends CustomPainter {
_HighlightPainter({
this.color,
required this.color,
this.style = _HighlightPainterStyle.none,
this.textDirection,
});
final Color color;
final _HighlightPainterStyle style;
final TextDirection textDirection;
final TextDirection? textDirection;
@override
void paint(Canvas canvas, Size size) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -61,8 +59,8 @@ class DateTimeRange {
///
/// [start] and [end] must be non-null.
const DateTimeRange({
@required this.start,
@required this.end,
required this.start,
required this.end,
}) : assert(start != null),
assert(end != null);
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'dart:math' as math;
......@@ -86,13 +84,13 @@ class DayPicker extends StatelessWidget {
///
/// Rarely used directly. Instead, typically used as part of a [MonthPicker].
DayPicker({
Key key,
@required this.selectedDate,
@required this.currentDate,
@required this.onChanged,
@required this.firstDate,
@required this.lastDate,
@required this.displayedMonth,
Key? key,
required this.selectedDate,
required this.currentDate,
required this.onChanged,
required this.firstDate,
required this.lastDate,
required this.displayedMonth,
this.selectableDayPredicate,
this.dragStartBehavior = DragStartBehavior.start,
}) : assert(selectedDate != null),
......@@ -125,7 +123,7 @@ class DayPicker extends StatelessWidget {
final DateTime displayedMonth;
/// Optional user supplied predicate function to customize selectable days.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
/// Determines the way that drag start behavior is handled.
///
......@@ -163,7 +161,7 @@ class DayPicker extends StatelessWidget {
/// _ _ _ _ 1 2 3
/// 4 5 6 7 8 9 10
/// ```
List<Widget> _getDayHeaders(TextStyle headerStyle, MaterialLocalizations localizations) {
List<Widget> _getDayHeaders(TextStyle? headerStyle, MaterialLocalizations localizations) {
final List<Widget> result = <Widget>[];
for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) {
final String weekday = localizations.narrowWeekdays[i];
......@@ -240,8 +238,8 @@ class DayPicker extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final ThemeData themeData = Theme.of(context)!;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final int year = displayedMonth.year;
final int month = displayedMonth.month;
final int daysInMonth = getDaysInMonth(year, month);
......@@ -261,10 +259,10 @@ class DayPicker extends StatelessWidget {
final DateTime dayToBuild = DateTime(year, month, day);
final bool disabled = dayToBuild.isAfter(lastDate)
|| dayToBuild.isBefore(firstDate)
|| (selectableDayPredicate != null && !selectableDayPredicate(dayToBuild));
|| (selectableDayPredicate != null && !selectableDayPredicate!(dayToBuild));
BoxDecoration decoration;
TextStyle itemStyle = themeData.textTheme.bodyText2;
BoxDecoration? decoration;
TextStyle? itemStyle = themeData.textTheme.bodyText2;
final bool isSelectedDay = selectedDate.year == year && selectedDate.month == month && selectedDate.day == day;
if (isSelectedDay) {
......@@ -275,10 +273,10 @@ class DayPicker extends StatelessWidget {
shape: BoxShape.circle,
);
} else if (disabled) {
itemStyle = themeData.textTheme.bodyText2.copyWith(color: themeData.disabledColor);
itemStyle = themeData.textTheme.bodyText2!.copyWith(color: themeData.disabledColor);
} else if (currentDate.year == year && currentDate.month == month && currentDate.day == day) {
// The current day gets a different text color.
itemStyle = themeData.textTheme.bodyText1.copyWith(color: themeData.accentColor);
itemStyle = themeData.textTheme.bodyText1!.copyWith(color: themeData.accentColor);
}
Widget dayWidget = Container(
......@@ -369,11 +367,11 @@ class MonthPicker extends StatefulWidget {
/// Rarely used directly. Instead, typically used as part of the dialog shown
/// by [showDatePicker].
MonthPicker({
Key key,
@required this.selectedDate,
@required this.onChanged,
@required this.firstDate,
@required this.lastDate,
Key? key,
required this.selectedDate,
required this.onChanged,
required this.firstDate,
required this.lastDate,
this.selectableDayPredicate,
this.dragStartBehavior = DragStartBehavior.start,
}) : assert(selectedDate != null),
......@@ -397,7 +395,7 @@ class MonthPicker extends StatefulWidget {
final DateTime lastDate;
/// Optional user supplied predicate function to customize selectable days.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
/// {@macro flutter.widgets.scrollable.dragStartBehavior}
final DragStartBehavior dragStartBehavior;
......@@ -436,8 +434,8 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
}
}
MaterialLocalizations localizations;
TextDirection textDirection;
MaterialLocalizations? localizations;
TextDirection? textDirection;
@override
void didChangeDependencies() {
......@@ -446,12 +444,12 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
textDirection = Directionality.of(context);
}
DateTime _todayDate;
DateTime _currentDisplayedMonthDate;
Timer _timer;
PageController _dayPickerController;
AnimationController _chevronOpacityController;
Animation<double> _chevronOpacityAnimation;
late DateTime _todayDate;
late DateTime _currentDisplayedMonthDate;
Timer? _timer;
late PageController _dayPickerController;
late AnimationController _chevronOpacityController;
late Animation<double> _chevronOpacityAnimation;
void _updateCurrentDate() {
_todayDate = DateTime.now();
......@@ -492,14 +490,14 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
void _handleNextMonth() {
if (!_isDisplayingLastMonth) {
SemanticsService.announce(localizations.formatMonthYear(_nextMonthDate), textDirection);
SemanticsService.announce(localizations!.formatMonthYear(_nextMonthDate), textDirection!);
_dayPickerController.nextPage(duration: _kMonthScrollDuration, curve: Curves.ease);
}
}
void _handlePreviousMonth() {
if (!_isDisplayingFirstMonth) {
SemanticsService.announce(localizations.formatMonthYear(_previousMonthDate), textDirection);
SemanticsService.announce(localizations!.formatMonthYear(_previousMonthDate), textDirection!);
_dayPickerController.previousPage(duration: _kMonthScrollDuration, curve: Curves.ease);
}
}
......@@ -516,8 +514,8 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
DateTime(widget.lastDate.year, widget.lastDate.month));
}
DateTime _previousMonthDate;
DateTime _nextMonthDate;
late DateTime _previousMonthDate;
late DateTime _nextMonthDate;
void _handleMonthPageChanged(int monthPage) {
setState(() {
......@@ -568,7 +566,7 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
opacity: _chevronOpacityAnimation,
child: IconButton(
icon: const Icon(Icons.chevron_left),
tooltip: _isDisplayingFirstMonth ? null : '${localizations.previousMonthTooltip} ${localizations.formatMonthYear(_previousMonthDate)}',
tooltip: _isDisplayingFirstMonth ? null : '${localizations!.previousMonthTooltip} ${localizations!.formatMonthYear(_previousMonthDate)}',
onPressed: _isDisplayingFirstMonth ? null : _handlePreviousMonth,
),
),
......@@ -583,7 +581,7 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
opacity: _chevronOpacityAnimation,
child: IconButton(
icon: const Icon(Icons.chevron_right),
tooltip: _isDisplayingLastMonth ? null : '${localizations.nextMonthTooltip} ${localizations.formatMonthYear(_nextMonthDate)}',
tooltip: _isDisplayingLastMonth ? null : '${localizations!.nextMonthTooltip} ${localizations!.formatMonthYear(_nextMonthDate)}',
onPressed: _isDisplayingLastMonth ? null : _handleNextMonth,
),
),
......@@ -597,8 +595,8 @@ class _MonthPickerState extends State<MonthPicker> with SingleTickerProviderStat
@override
void dispose() {
_timer?.cancel();
_chevronOpacityController?.dispose();
_dayPickerController?.dispose();
_chevronOpacityController.dispose();
_dayPickerController.dispose();
super.dispose();
}
}
......@@ -640,11 +638,11 @@ class YearPicker extends StatefulWidget {
/// Rarely used directly. Instead, typically used as part of the dialog shown
/// by [showDatePicker].
YearPicker({
Key key,
@required this.selectedDate,
@required this.onChanged,
@required this.firstDate,
@required this.lastDate,
Key? key,
required this.selectedDate,
required this.onChanged,
required this.firstDate,
required this.lastDate,
this.dragStartBehavior = DragStartBehavior.start,
}) : assert(selectedDate != null),
assert(onChanged != null),
......@@ -674,7 +672,7 @@ class YearPicker extends StatefulWidget {
class _YearPickerState extends State<YearPicker> {
static const double _itemExtent = 50.0;
ScrollController scrollController;
late ScrollController scrollController;
@override
void initState() {
......@@ -688,8 +686,8 @@ class _YearPickerState extends State<YearPicker> {
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
final ThemeData themeData = Theme.of(context);
final TextStyle style = themeData.textTheme.bodyText2;
final ThemeData themeData = Theme.of(context)!;
final TextStyle? style = themeData.textTheme.bodyText2;
return ListView.builder(
dragStartBehavior: widget.dragStartBehavior,
controller: scrollController,
......@@ -698,8 +696,8 @@ class _YearPickerState extends State<YearPicker> {
itemBuilder: (BuildContext context, int index) {
final int year = widget.firstDate.year + index;
final bool isSelected = year == widget.selectedDate.year;
final TextStyle itemStyle = isSelected
? themeData.textTheme.headline5.copyWith(color: themeData.accentColor)
final TextStyle? itemStyle = isSelected
? themeData.textTheme.headline5!.copyWith(color: themeData.accentColor)
: style;
return InkWell(
key: ValueKey<int>(year),
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'package:flutter/services.dart';
......@@ -102,26 +100,26 @@ const double _inputFormLandscapeHeight = 108.0;
/// * [InputDatePickerFormField], which provides a text input field for entering dates.
///
Future<DateTime> showDatePicker({
@required BuildContext context,
@required DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
required BuildContext context,
required DateTime initialDate,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar,
SelectableDayPredicate selectableDayPredicate,
String helpText,
String cancelText,
String confirmText,
Locale locale,
SelectableDayPredicate? selectableDayPredicate,
String? helpText,
String? cancelText,
String? confirmText,
Locale? locale,
bool useRootNavigator = true,
RouteSettings routeSettings,
TextDirection textDirection,
TransitionBuilder builder,
RouteSettings? routeSettings,
TextDirection? textDirection,
TransitionBuilder? builder,
DatePickerMode initialDatePickerMode = DatePickerMode.day,
String errorFormatText,
String errorInvalidText,
String fieldHintText,
String fieldLabelText,
String? errorFormatText,
String? errorInvalidText,
String? fieldHintText,
String? fieldLabelText,
}) async {
assert(context != null);
assert(initialDate != null);
......@@ -195,11 +193,11 @@ Future<DateTime> showDatePicker({
class _DatePickerDialog extends StatefulWidget {
_DatePickerDialog({
Key key,
@required DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
Key? key,
required DateTime initialDate,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
this.initialEntryMode = DatePickerEntryMode.calendar,
this.selectableDayPredicate,
this.cancelText,
......@@ -233,7 +231,7 @@ class _DatePickerDialog extends StatefulWidget {
'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.'
);
assert(
selectableDayPredicate == null || selectableDayPredicate(this.initialDate),
selectableDayPredicate == null || selectableDayPredicate!(this.initialDate),
'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate'
);
}
......@@ -253,29 +251,29 @@ class _DatePickerDialog extends StatefulWidget {
final DatePickerEntryMode initialEntryMode;
/// Function to provide full control over which [DateTime] can be selected.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
/// The text that is displayed on the cancel button.
final String cancelText;
final String? cancelText;
/// The text that is displayed on the confirm button.
final String confirmText;
final String? confirmText;
/// The text that is displayed at the top of the header.
///
/// This is used to indicate to the user what they are selecting a date for.
final String helpText;
final String? helpText;
/// The initial display of the calendar picker.
final DatePickerMode initialCalendarMode;
final String errorFormatText;
final String? errorFormatText;
final String errorInvalidText;
final String? errorInvalidText;
final String fieldHintText;
final String? fieldHintText;
final String fieldLabelText;
final String? fieldLabelText;
@override
_DatePickerDialogState createState() => _DatePickerDialogState();
......@@ -283,9 +281,9 @@ class _DatePickerDialog extends StatefulWidget {
class _DatePickerDialogState extends State<_DatePickerDialog> {
DatePickerEntryMode _entryMode;
DateTime _selectedDate;
bool _autoValidate;
late DatePickerEntryMode _entryMode;
late DateTime _selectedDate;
late bool _autoValidate;
final GlobalKey _calendarPickerKey = GlobalKey();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
......@@ -299,7 +297,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
void _handleOk() {
if (_entryMode == DatePickerEntryMode.input) {
final FormState form = _formKey.currentState;
final FormState form = _formKey.currentState!;
if (!form.validate()) {
setState(() => _autoValidate = true);
return;
......@@ -321,7 +319,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
_entryMode = DatePickerEntryMode.input;
break;
case DatePickerEntryMode.input:
_formKey.currentState.save();
_formKey.currentState!.save();
_entryMode = DatePickerEntryMode.calendar;
break;
}
......@@ -333,7 +331,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
}
Size _dialogSize(BuildContext context) {
final Orientation orientation = MediaQuery.of(context).orientation;
final Orientation orientation = MediaQuery.of(context)!.orientation;
switch (_entryMode) {
case DatePickerEntryMode.calendar:
switch (orientation) {
......@@ -342,7 +340,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
case Orientation.landscape:
return _calendarLandscapeDialogSize;
}
break;
case DatePickerEntryMode.input:
switch (orientation) {
case Orientation.portrait:
......@@ -350,9 +347,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
case Orientation.landscape:
return _inputLandscapeDialogSize;
}
break;
}
return null;
}
static final Map<LogicalKeySet, Intent> _formShortcutMap = <LogicalKeySet, Intent>{
......@@ -362,22 +357,20 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final Orientation orientation = MediaQuery.of(context)!.orientation;
final TextTheme textTheme = theme.textTheme;
// Constrain the textScaleFactor to the largest supported value to prevent
// layout issues.
final double textScaleFactor = math.min(MediaQuery.of(context).textScaleFactor, 1.3);
final double textScaleFactor = math.min(MediaQuery.of(context)!.textScaleFactor, 1.3);
final String dateText = _selectedDate != null
? localizations.formatMediumDate(_selectedDate)
: localizations.unspecifiedDate;
final String dateText = localizations.formatMediumDate(_selectedDate);
final Color dateColor = colorScheme.brightness == Brightness.light
? colorScheme.onPrimary
: colorScheme.onSurface;
final TextStyle dateStyle = orientation == Orientation.landscape
final TextStyle? dateStyle = orientation == Orientation.landscape
? textTheme.headline5?.copyWith(color: dateColor)
: textTheme.headline4?.copyWith(color: dateColor);
......@@ -474,7 +467,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
duration: _dialogSizeAnimationDuration,
curve: Curves.easeIn,
child: MediaQuery(
data: MediaQuery.of(context).copyWith(
data: MediaQuery.of(context)!.copyWith(
textScaleFactor: textScaleFactor,
),
child: Builder(builder: (BuildContext context) {
......@@ -508,7 +501,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
],
);
}
return null;
}),
),
),
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/widgets.dart';
import '../color_scheme.dart';
......@@ -35,16 +33,16 @@ const double _headerPaddingLandscape = 16.0;
class DatePickerHeader extends StatelessWidget {
/// Creates a header for use in a date picker dialog.
const DatePickerHeader({
Key key,
@required this.helpText,
@required this.titleText,
Key? key,
required this.helpText,
required this.titleText,
this.titleSemanticsLabel,
@required this.titleStyle,
@required this.orientation,
required this.titleStyle,
required this.orientation,
this.isShort = false,
@required this.icon,
@required this.iconTooltip,
@required this.onIconPressed,
required this.icon,
required this.iconTooltip,
required this.onIconPressed,
}) : assert(helpText != null),
assert(orientation != null),
assert(isShort != null),
......@@ -59,10 +57,10 @@ class DatePickerHeader extends StatelessWidget {
final String titleText;
/// The semantic label associated with the [titleText].
final String titleSemanticsLabel;
final String? titleSemanticsLabel;
/// The [TextStyle] that the title text is displayed with.
final TextStyle titleStyle;
final TextStyle? titleStyle;
/// The orientation is used to decide how to layout its children.
final Orientation orientation;
......@@ -93,7 +91,7 @@ class DatePickerHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final TextTheme textTheme = theme.textTheme;
......@@ -102,7 +100,7 @@ class DatePickerHeader extends StatelessWidget {
final Color primarySurfaceColor = isDark ? colorScheme.surface : colorScheme.primary;
final Color onPrimarySurfaceColor = isDark ? colorScheme.onSurface : colorScheme.onPrimary;
final TextStyle helpStyle = textTheme.overline?.copyWith(
final TextStyle? helpStyle = textTheme.overline?.copyWith(
color: onPrimarySurfaceColor,
);
......@@ -189,6 +187,5 @@ class DatePickerHeader extends StatelessWidget {
),
);
}
return null;
}
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'package:flutter/rendering.dart';
......@@ -109,28 +107,28 @@ const double _inputFormLandscapeHeight = 108.0;
/// * [DateTimeRange], which is used to describe a date range.
///
Future<DateTimeRange> showDateRangePicker({
@required BuildContext context,
DateTimeRange initialDateRange,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
required BuildContext context,
DateTimeRange? initialDateRange,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar,
String helpText,
String cancelText,
String confirmText,
String saveText,
String errorFormatText,
String errorInvalidText,
String errorInvalidRangeText,
String fieldStartHintText,
String fieldEndHintText,
String fieldStartLabelText,
String fieldEndLabelText,
Locale locale,
String? helpText,
String? cancelText,
String? confirmText,
String? saveText,
String? errorFormatText,
String? errorInvalidText,
String? errorInvalidRangeText,
String? fieldStartHintText,
String? fieldEndHintText,
String? fieldStartLabelText,
String? fieldEndLabelText,
Locale? locale,
bool useRootNavigator = true,
RouteSettings routeSettings,
TextDirection textDirection,
TransitionBuilder builder,
RouteSettings? routeSettings,
TextDirection? textDirection,
TransitionBuilder? builder,
}) async {
assert(context != null);
assert(
......@@ -218,10 +216,10 @@ Future<DateTimeRange> showDateRangePicker({
class _DateRangePickerDialog extends StatefulWidget {
const _DateRangePickerDialog({
Key key,
Key? key,
this.initialDateRange,
@required this.firstDate,
@required this.lastDate,
required this.firstDate,
required this.lastDate,
this.currentDate,
this.initialEntryMode = DatePickerEntryMode.calendar,
this.helpText,
......@@ -237,32 +235,32 @@ class _DateRangePickerDialog extends StatefulWidget {
this.fieldEndLabelText,
}) : super(key: key);
final DateTimeRange initialDateRange;
final DateTimeRange? initialDateRange;
final DateTime firstDate;
final DateTime lastDate;
final DateTime currentDate;
final DateTime? currentDate;
final DatePickerEntryMode initialEntryMode;
final String cancelText;
final String confirmText;
final String saveText;
final String helpText;
final String errorInvalidRangeText;
final String errorFormatText;
final String errorInvalidText;
final String fieldStartHintText;
final String fieldEndHintText;
final String fieldStartLabelText;
final String fieldEndLabelText;
final String? cancelText;
final String? confirmText;
final String? saveText;
final String? helpText;
final String? errorInvalidRangeText;
final String? errorFormatText;
final String? errorInvalidText;
final String? fieldStartHintText;
final String? fieldEndHintText;
final String? fieldStartLabelText;
final String? fieldEndLabelText;
@override
_DateRangePickerDialogState createState() => _DateRangePickerDialogState();
}
class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
DatePickerEntryMode _entryMode;
DateTime _selectedStart;
DateTime _selectedEnd;
bool _autoValidate;
late DatePickerEntryMode _entryMode;
DateTime? _selectedStart;
DateTime? _selectedEnd;
late bool _autoValidate;
final GlobalKey _calendarPickerKey = GlobalKey();
final GlobalKey<InputDateRangePickerState> _inputPickerKey = GlobalKey<InputDateRangePickerState>();
......@@ -277,7 +275,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
void _handleOk() {
if (_entryMode == DatePickerEntryMode.input) {
final InputDateRangePickerState picker = _inputPickerKey.currentState;
final InputDateRangePickerState picker = _inputPickerKey.currentState!;
if (!picker.validate()) {
setState(() {
_autoValidate = true;
......@@ -285,8 +283,8 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
return;
}
}
final DateTimeRange selectedRange = _hasSelectedDateRange
? DateTimeRange(start: _selectedStart, end: _selectedEnd)
final DateTimeRange? selectedRange = _hasSelectedDateRange
? DateTimeRange(start: _selectedStart!, end: _selectedEnd!)
: null;
Navigator.pop(context, selectedRange);
......@@ -306,7 +304,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
case DatePickerEntryMode.input:
// If invalid range (start after end), then just use the start date
if (_selectedStart != null && _selectedEnd != null && _selectedStart.isAfter(_selectedEnd)) {
if (_selectedStart != null && _selectedEnd != null && _selectedStart!.isAfter(_selectedEnd!)) {
_selectedEnd = null;
}
_entryMode = DatePickerEntryMode.calendar;
......@@ -319,7 +317,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
setState(() => _selectedStart = date);
}
void _handleEndDateChanged(DateTime date) {
void _handleEndDateChanged(DateTime? date) {
setState(() => _selectedEnd = date);
}
......@@ -327,14 +325,14 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
@override
Widget build(BuildContext context) {
final MediaQueryData mediaQuery = MediaQuery.of(context);
final MediaQueryData mediaQuery = MediaQuery.of(context)!;
final Orientation orientation = mediaQuery.orientation;
final double textScaleFactor = math.min(mediaQuery.textScaleFactor, 1.3);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
Widget contents;
Size size;
ShapeBorder shape;
ShapeBorder? shape;
double elevation;
EdgeInsets insetPadding;
switch (_entryMode) {
......@@ -405,7 +403,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
cancelText: widget.cancelText ?? localizations.cancelButtonLabel,
helpText: widget.helpText ?? localizations.dateRangePickerHelpText,
);
final DialogTheme dialogTheme = Theme.of(context).dialogTheme;
final DialogTheme dialogTheme = Theme.of(context)!.dialogTheme;
size = orientation == Orientation.portrait ? _inputPortraitDialogSize : _inputLandscapeDialogSize;
insetPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0);
shape = dialogTheme.shape;
......@@ -420,7 +418,7 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
duration: _dialogSizeAnimationDuration,
curve: Curves.easeIn,
child: MediaQuery(
data: MediaQuery.of(context).copyWith(
data: MediaQuery.of(context)!.copyWith(
textScaleFactor: textScaleFactor,
),
child: Builder(builder: (BuildContext context) {
......@@ -438,40 +436,40 @@ class _DateRangePickerDialogState extends State<_DateRangePickerDialog> {
class _CalendarRangePickerDialog extends StatelessWidget {
const _CalendarRangePickerDialog({
Key key,
@required this.selectedStartDate,
@required this.selectedEndDate,
@required this.firstDate,
@required this.lastDate,
@required this.currentDate,
@required this.onStartDateChanged,
@required this.onEndDateChanged,
@required this.onConfirm,
@required this.onCancel,
@required this.onToggleEntryMode,
@required this.confirmText,
@required this.helpText,
Key? key,
required this.selectedStartDate,
required this.selectedEndDate,
required this.firstDate,
required this.lastDate,
required this.currentDate,
required this.onStartDateChanged,
required this.onEndDateChanged,
required this.onConfirm,
required this.onCancel,
required this.onToggleEntryMode,
required this.confirmText,
required this.helpText,
}) : super(key: key);
final DateTime selectedStartDate;
final DateTime selectedEndDate;
final DateTime? selectedStartDate;
final DateTime? selectedEndDate;
final DateTime firstDate;
final DateTime lastDate;
final DateTime currentDate;
final DateTime? currentDate;
final ValueChanged<DateTime> onStartDateChanged;
final ValueChanged<DateTime> onEndDateChanged;
final VoidCallback onConfirm;
final VoidCallback onCancel;
final VoidCallback onToggleEntryMode;
final ValueChanged<DateTime?> onEndDateChanged;
final VoidCallback? onConfirm;
final VoidCallback? onCancel;
final VoidCallback? onToggleEntryMode;
final String confirmText;
final String helpText;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final Orientation orientation = MediaQuery.of(context)!.orientation;
final TextTheme textTheme = theme.textTheme;
final Color headerForeground = colorScheme.brightness == Brightness.light
? colorScheme.onPrimary
......@@ -479,14 +477,14 @@ class _CalendarRangePickerDialog extends StatelessWidget {
final Color headerDisabledForeground = headerForeground.withOpacity(0.38);
final String startDateText = utils.formatRangeStartDate(localizations, selectedStartDate, selectedEndDate);
final String endDateText = utils.formatRangeEndDate(localizations, selectedStartDate, selectedEndDate, DateTime.now());
final TextStyle headlineStyle = textTheme.headline5;
final TextStyle startDateStyle = headlineStyle?.apply(
final TextStyle? headlineStyle = textTheme.headline5;
final TextStyle? startDateStyle = headlineStyle?.apply(
color: selectedStartDate != null ? headerForeground : headerDisabledForeground
);
final TextStyle endDateStyle = headlineStyle?.apply(
final TextStyle? endDateStyle = headlineStyle?.apply(
color: selectedEndDate != null ? headerForeground : headerDisabledForeground
);
final TextStyle saveButtonStyle = textTheme.button.apply(
final TextStyle saveButtonStyle = textTheme.button!.apply(
color: onConfirm != null ? headerForeground : headerDisabledForeground
);
......@@ -520,7 +518,7 @@ class _CalendarRangePickerDialog extends StatelessWidget {
],
bottom: PreferredSize(
child: Row(children: <Widget>[
SizedBox(width: MediaQuery.of(context).size.width < 360 ? 42 : 72),
SizedBox(width: MediaQuery.of(context)!.size.width < 360 ? 42 : 72),
Expanded(
child: Semantics(
label: '$helpText $startDateText to $endDateText',
......@@ -530,7 +528,7 @@ class _CalendarRangePickerDialog extends StatelessWidget {
children: <Widget>[
Text(
helpText,
style: textTheme.overline.apply(
style: textTheme.overline!.apply(
color: headerForeground,
),
),
......@@ -585,32 +583,32 @@ class _CalendarRangePickerDialog extends StatelessWidget {
class _InputDateRangePickerDialog extends StatelessWidget {
const _InputDateRangePickerDialog({
Key key,
@required this.selectedStartDate,
@required this.selectedEndDate,
@required this.currentDate,
@required this.picker,
@required this.onConfirm,
@required this.onCancel,
@required this.onToggleEntryMode,
@required this.confirmText,
@required this.cancelText,
@required this.helpText,
Key? key,
required this.selectedStartDate,
required this.selectedEndDate,
required this.currentDate,
required this.picker,
required this.onConfirm,
required this.onCancel,
required this.onToggleEntryMode,
required this.confirmText,
required this.cancelText,
required this.helpText,
}) : super(key: key);
final DateTime selectedStartDate;
final DateTime selectedEndDate;
final DateTime currentDate;
final DateTime? selectedStartDate;
final DateTime? selectedEndDate;
final DateTime? currentDate;
final Widget picker;
final VoidCallback onConfirm;
final VoidCallback onCancel;
final VoidCallback onToggleEntryMode;
final String confirmText;
final String cancelText;
final String helpText;
final String? confirmText;
final String? cancelText;
final String? helpText;
String _formatDateRange(BuildContext context, DateTime start, DateTime end, DateTime now) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
String _formatDateRange(BuildContext context, DateTime? start, DateTime? end, DateTime now) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final String startText = utils.formatRangeStartDate(localizations, start, end);
final String endText = utils.formatRangeEndDate(localizations, start, end, now);
if (start == null || end == null) {
......@@ -625,21 +623,21 @@ class _InputDateRangePickerDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final Orientation orientation = MediaQuery.of(context)!.orientation;
final TextTheme textTheme = theme.textTheme;
final Color dateColor = colorScheme.brightness == Brightness.light
? colorScheme.onPrimary
: colorScheme.onSurface;
final TextStyle dateStyle = orientation == Orientation.landscape
final TextStyle? dateStyle = orientation == Orientation.landscape
? textTheme.headline5?.apply(color: dateColor)
: textTheme.headline4?.apply(color: dateColor);
final String dateText = _formatDateRange(context, selectedStartDate, selectedEndDate, currentDate);
final String dateText = _formatDateRange(context, selectedStartDate, selectedEndDate, currentDate!);
final String semanticDateText = selectedStartDate != null && selectedEndDate != null
? '${localizations.formatMediumDate(selectedStartDate)}${localizations.formatMediumDate(selectedEndDate)}'
? '${localizations.formatMediumDate(selectedStartDate!)}${localizations.formatMediumDate(selectedEndDate!)}'
: '';
final Widget header = DatePickerHeader(
......@@ -704,6 +702,5 @@ class _InputDateRangePickerDialog extends StatelessWidget {
],
);
}
return null;
}
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// Common date utility functions used by the date picker implementation
// This is an internal implementation file. Even though there are public
......@@ -27,7 +25,7 @@ DateTimeRange datesOnly(DateTimeRange range) {
/// Returns true if the two [DateTime] objects have the same day, month, and
/// year, or are both null.
bool isSameDay(DateTime dateA, DateTime dateB) {
bool isSameDay(DateTime? dateA, DateTime? dateB) {
return
dateA?.year == dateB?.year &&
dateA?.month == dateB?.month &&
......@@ -36,7 +34,7 @@ bool isSameDay(DateTime dateA, DateTime dateB) {
/// Returns true if the two [DateTime] objects have the same month, and
/// year, or are both null.
bool isSameMonth(DateTime dateA, DateTime dateB) {
bool isSameMonth(DateTime? dateA, DateTime? dateB) {
return
dateA?.year == dateB?.year &&
dateA?.month == dateB?.month;
......@@ -148,7 +146,7 @@ int getDaysInMonth(int year, int month) {
/// is in the same year as the `endDate` then it will use the short month
/// day format (i.e. 'Jan 21'). Otherwise it will return the short date format
/// (i.e. 'Jan 21, 2020').
String formatRangeStartDate(MaterialLocalizations localizations, DateTime startDate, DateTime endDate) {
String formatRangeStartDate(MaterialLocalizations localizations, DateTime? startDate, DateTime? endDate) {
return startDate == null
? localizations.dateRangeStartLabel
: (endDate == null || startDate.year == endDate.year)
......@@ -162,7 +160,7 @@ String formatRangeStartDate(MaterialLocalizations localizations, DateTime startD
/// is in the same year as the `startDate` and the `currentDate` then it will
/// just use the short month day format (i.e. 'Jan 21'), otherwise it will
/// include the year (i.e. 'Jan 21, 2020').
String formatRangeEndDate(MaterialLocalizations localizations, DateTime startDate, DateTime endDate, DateTime currentDate) {
String formatRangeEndDate(MaterialLocalizations localizations, DateTime? startDate, DateTime? endDate, DateTime currentDate) {
return endDate == null
? localizations.dateRangeEndLabel
: (startDate != null && startDate.year == endDate.year && startDate.year == currentDate.year)
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
......@@ -50,10 +48,10 @@ class InputDatePickerFormField extends StatefulWidget {
/// [firstDate], [lastDate], and [autofocus] must be non-null.
///
InputDatePickerFormField({
Key key,
DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
Key? key,
DateTime? initialDate,
required DateTime firstDate,
required DateTime lastDate,
this.onDateSubmitted,
this.onDateSaved,
this.selectableDayPredicate,
......@@ -74,21 +72,21 @@ class InputDatePickerFormField extends StatefulWidget {
'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.'
);
assert(
initialDate == null || !this.initialDate.isBefore(this.firstDate),
initialDate == null || !this.initialDate!.isBefore(this.firstDate),
'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.'
);
assert(
initialDate == null || !this.initialDate.isAfter(this.lastDate),
initialDate == null || !this.initialDate!.isAfter(this.lastDate),
'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.'
);
assert(
selectableDayPredicate == null || initialDate == null || selectableDayPredicate(this.initialDate),
selectableDayPredicate == null || initialDate == null || selectableDayPredicate!(this.initialDate!),
'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate.'
);
}
/// If provided, it will be used as the default value of the field.
final DateTime initialDate;
final DateTime? initialDate;
/// The earliest allowable [DateTime] that the user can input.
final DateTime firstDate;
......@@ -99,36 +97,36 @@ class InputDatePickerFormField extends StatefulWidget {
/// An optional method to call when the user indicates they are done editing
/// the text in the field. Will only be called if the input represents a valid
/// [DateTime].
final ValueChanged<DateTime> onDateSubmitted;
final ValueChanged<DateTime>? onDateSubmitted;
/// An optional method to call with the final date when the form is
/// saved via [FormState.save]. Will only be called if the input represents
/// a valid [DateTime].
final ValueChanged<DateTime> onDateSaved;
final ValueChanged<DateTime>? onDateSaved;
/// Function to provide full control over which [DateTime] can be selected.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
/// The error text displayed if the entered date is not in the correct format.
final String errorFormatText;
final String? errorFormatText;
/// The error text displayed if the date is not valid.
///
/// A date is not valid if it is earlier than [firstDate], later than
/// [lastDate], or doesn't pass the [selectableDayPredicate].
final String errorInvalidText;
final String? errorInvalidText;
/// The hint text displayed in the [TextField].
///
/// If this is null, it will default to the date format string. For example,
/// 'mm/dd/yyyy' for en_US.
final String fieldHintText;
final String? fieldHintText;
/// The label text displayed in the [TextField].
///
/// If this is null, it will default to the words representing the date format
/// string. For example, 'Month, Day, Year' for en_US.
final String fieldLabelText;
final String? fieldLabelText;
/// {@macro flutter.widgets.editableText.autofocus}
final bool autofocus;
......@@ -139,8 +137,8 @@ class InputDatePickerFormField extends StatefulWidget {
class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
final TextEditingController _controller = TextEditingController();
DateTime _selectedDate;
String _inputText;
DateTime? _selectedDate;
String? _inputText;
bool _autoSelected = false;
@override
......@@ -159,14 +157,14 @@ class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
void didChangeDependencies() {
super.didChangeDependencies();
if (_selectedDate != null) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
_inputText = localizations.formatCompactDate(_selectedDate);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
_inputText = localizations.formatCompactDate(_selectedDate!);
TextEditingValue textEditingValue = _controller.value.copyWith(text: _inputText);
// Select the new text if we are auto focused and haven't selected the text before.
if (widget.autofocus && !_autoSelected) {
textEditingValue = textEditingValue.copyWith(selection: TextSelection(
baseOffset: 0,
extentOffset: _inputText.length,
extentOffset: _inputText!.length,
));
_autoSelected = true;
}
......@@ -174,55 +172,55 @@ class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
}
}
DateTime _parseDate(String text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
DateTime? _parseDate(String? text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
return localizations.parseCompactDate(text);
}
bool _isValidAcceptableDate(DateTime date) {
bool _isValidAcceptableDate(DateTime? date) {
return
date != null &&
!date.isBefore(widget.firstDate) &&
!date.isAfter(widget.lastDate) &&
(widget.selectableDayPredicate == null || widget.selectableDayPredicate(date));
(widget.selectableDayPredicate == null || widget.selectableDayPredicate!(date));
}
String _validateDate(String text) {
final DateTime date = _parseDate(text);
String? _validateDate(String? text) {
final DateTime? date = _parseDate(text);
if (date == null) {
return widget.errorFormatText ?? MaterialLocalizations.of(context).invalidDateFormatLabel;
return widget.errorFormatText ?? MaterialLocalizations.of(context)!.invalidDateFormatLabel;
} else if (!_isValidAcceptableDate(date)) {
return widget.errorInvalidText ?? MaterialLocalizations.of(context).dateOutOfRangeLabel;
return widget.errorInvalidText ?? MaterialLocalizations.of(context)!.dateOutOfRangeLabel;
}
return null;
}
void _handleSaved(String text) {
void _handleSaved(String? text) {
if (widget.onDateSaved != null) {
final DateTime date = _parseDate(text);
final DateTime? date = _parseDate(text);
if (_isValidAcceptableDate(date)) {
_selectedDate = date;
_inputText = text;
widget.onDateSaved(date);
widget.onDateSaved!(date!);
}
}
}
void _handleSubmitted(String text) {
if (widget.onDateSubmitted != null) {
final DateTime date = _parseDate(text);
final DateTime? date = _parseDate(text);
if (_isValidAcceptableDate(date)) {
_selectedDate = date;
_inputText = text;
widget.onDateSubmitted(date);
widget.onDateSubmitted!(date!);
}
}
}
@override
Widget build(BuildContext context) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final InputDecorationTheme inputTheme = Theme.of(context).inputDecorationTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final InputDecorationTheme inputTheme = Theme.of(context)!.inputDecorationTheme;
return TextFormField(
decoration: InputDecoration(
border: inputTheme.border ?? const UnderlineInputBorder(),
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
......@@ -24,13 +22,13 @@ class InputDateRangePicker extends StatefulWidget {
/// Creates a row with two text fields configured to accept the start and end dates
/// of a date range.
InputDateRangePicker({
Key key,
DateTime initialStartDate,
DateTime initialEndDate,
@required DateTime firstDate,
@required DateTime lastDate,
@required this.onStartDateChanged,
@required this.onEndDateChanged,
Key? key,
DateTime? initialStartDate,
DateTime? initialEndDate,
required DateTime firstDate,
required DateTime lastDate,
required this.onStartDateChanged,
required this.onEndDateChanged,
this.helpText,
this.errorFormatText,
this.errorInvalidText,
......@@ -54,10 +52,10 @@ class InputDateRangePicker extends StatefulWidget {
super(key: key);
/// The [DateTime] that represents the start of the initial date range selection.
final DateTime initialStartDate;
final DateTime? initialStartDate;
/// The [DateTime] that represents the end of the initial date range selection.
final DateTime initialEndDate;
final DateTime? initialEndDate;
/// The earliest allowable [DateTime] that the user can select.
final DateTime firstDate;
......@@ -66,38 +64,38 @@ class InputDateRangePicker extends StatefulWidget {
final DateTime lastDate;
/// Called when the user changes the start date of the selected range.
final ValueChanged<DateTime> onStartDateChanged;
final ValueChanged<DateTime>? onStartDateChanged;
/// Called when the user changes the end date of the selected range.
final ValueChanged<DateTime> onEndDateChanged;
final ValueChanged<DateTime>? onEndDateChanged;
/// The text that is displayed at the top of the header.
///
/// This is used to indicate to the user what they are selecting a date for.
final String helpText;
final String? helpText;
/// Error text used to indicate the text in a field is not a valid date.
final String errorFormatText;
final String? errorFormatText;
/// Error text used to indicate the date in a field is not in the valid range
/// of [firstDate] - [lastDate].
final String errorInvalidText;
final String? errorInvalidText;
/// Error text used to indicate the dates given don't form a valid date
/// range (i.e. the start date is after the end date).
final String errorInvalidRangeText;
final String? errorInvalidRangeText;
/// Hint text shown when the start date field is empty.
final String fieldStartHintText;
final String? fieldStartHintText;
/// Hint text shown when the end date field is empty.
final String fieldEndHintText;
final String? fieldEndHintText;
/// Label used for the start date field.
final String fieldStartLabelText;
final String? fieldStartLabelText;
/// Label used for the end date field.
final String fieldEndLabelText;
final String? fieldEndLabelText;
/// {@macro flutter.widgets.editableText.autofocus}
final bool autofocus;
......@@ -114,14 +112,14 @@ class InputDateRangePicker extends StatefulWidget {
/// The current state of an [InputDateRangePicker]. Can be used to
/// [validate] the date field entries.
class InputDateRangePickerState extends State<InputDateRangePicker> {
String _startInputText;
String _endInputText;
DateTime _startDate;
DateTime _endDate;
TextEditingController _startController;
TextEditingController _endController;
String _startErrorText;
String _endErrorText;
late String _startInputText;
late String _endInputText;
DateTime? _startDate;
DateTime? _endDate;
late TextEditingController _startController;
late TextEditingController _endController;
String? _startErrorText;
String? _endErrorText;
bool _autoSelected = false;
@override
......@@ -143,16 +141,16 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
if (_startDate != null) {
_startInputText = localizations.formatCompactDate(_startDate);
_startInputText = localizations.formatCompactDate(_startDate!);
final bool selectText = widget.autofocus && !_autoSelected;
_updateController(_startController, _startInputText, selectText);
_autoSelected = selectText;
}
if (_endDate != null) {
_endInputText = localizations.formatCompactDate(_endDate);
_endInputText = localizations.formatCompactDate(_endDate!);
_updateController(_endController, _endInputText, false);
}
}
......@@ -164,11 +162,11 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
/// return false and display an appropriate error message under one of the
/// text fields.
bool validate() {
String startError = _validateDate(_startDate);
final String endError = _validateDate(_endDate);
String? startError = _validateDate(_startDate);
final String? endError = _validateDate(_endDate);
if (startError == null && endError == null) {
if (_startDate.isAfter(_endDate)) {
startError = widget.errorInvalidRangeText ?? MaterialLocalizations.of(context).invalidDateRangeLabel;
if (_startDate!.isAfter(_endDate!)) {
startError = widget.errorInvalidRangeText ?? MaterialLocalizations.of(context)!.invalidDateRangeLabel;
}
}
setState(() {
......@@ -178,16 +176,16 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
return startError == null && endError == null;
}
DateTime _parseDate(String text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
DateTime? _parseDate(String? text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
return localizations.parseCompactDate(text);
}
String _validateDate(DateTime date) {
String? _validateDate(DateTime? date) {
if (date == null) {
return widget.errorFormatText ?? MaterialLocalizations.of(context).invalidDateFormatLabel;
return widget.errorFormatText ?? MaterialLocalizations.of(context)!.invalidDateFormatLabel;
} else if (date.isBefore(widget.firstDate) || date.isAfter(widget.lastDate)) {
return widget.errorInvalidText ?? MaterialLocalizations.of(context).dateOutOfRangeLabel;
return widget.errorInvalidText ?? MaterialLocalizations.of(context)!.dateOutOfRangeLabel;
}
return null;
}
......@@ -207,7 +205,7 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
setState(() {
_startInputText = text;
_startDate = _parseDate(text);
widget.onStartDateChanged?.call(_startDate);
widget.onStartDateChanged?.call(_startDate!);
});
if (widget.autovalidate) {
validate();
......@@ -218,7 +216,7 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
setState(() {
_endInputText = text;
_endDate = _parseDate(text);
widget.onEndDateChanged?.call(_endDate);
widget.onEndDateChanged?.call(_endDate!);
});
if (widget.autovalidate) {
validate();
......@@ -227,8 +225,8 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
@override
Widget build(BuildContext context) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final InputDecorationTheme inputTheme = Theme.of(context).inputDecorationTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final InputDecorationTheme inputTheme = Theme.of(context)!.inputDecorationTheme;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// Date Picker public API
export 'calendar_date_picker.dart' show CalendarDatePicker;
export 'date_picker_common.dart' show
......
......@@ -193,9 +193,9 @@ class TestCase {
makeAbsolute(pubspec, workingDirectory: privateTestsDir)
.copySync(path.join(tmpdir.absolute.path, 'pubspec.yaml'));
// Copy Flutter's analysis_options.yaml file to the root of the tmpdir.
makeAbsolute(File('analysis_options.yaml'), workingDirectory: flutterRoot)
.copySync(path.join(tmpdir.absolute.path, 'analysis_options.yaml'));
// Use Flutter's analysis_options.yaml file from packages/flutter.
File(path.join(tmpdir.absolute.path, 'analysis_options.yaml'))
.writeAsStringSync('include: ${path.toUri(path.join(flutterRoot.path, 'packages', 'flutter', 'analysis_options.yaml'))}');
return true;
}
......@@ -225,7 +225,7 @@ class TestCase {
for (final File test in tests) {
final String testPath = path.join(path.dirname(test.path), 'lib', path.basenameWithoutExtension(test.path));
final ProcessRunnerResult result = await runner.runProcess(
<String>[flutter, 'test', testPath],
<String>[flutter, 'test', '--enable-experiment=non-nullable', '--null-assertions', testPath],
failOk: true,
);
if (result.exitCode != 0) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This is the test for the private implementation of animated icons.
// To make the private API accessible from the test we do not import the
// material material_animated_icons library, but instead, this test file is an
......@@ -17,7 +15,6 @@ import 'dart:ui' as ui show Paint, Path, Canvas;
import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
import 'test/flutter_test_alternative.dart';
......@@ -82,10 +79,10 @@ void main() {
group('_AnimatedIconPainter', () {
const Size size = Size(48.0, 48.0);
MockPath mockPath;
MockCanvas mockCanvas;
List<MockPath> generatedPaths;
_UiPathFactory pathFactory;
late MockPath mockPath;
late MockCanvas mockCanvas;
late List<MockPath> generatedPaths;
late _UiPathFactory pathFactory;
setUp(() {
generatedPaths = <MockPath>[];
......@@ -365,12 +362,12 @@ class MockCall {
final Symbol memberSymbol;
String get memberName {
final RegExp symbolMatch = RegExp(r'Symbol\("(?<name>.*)"\)');
final RegExpMatch match = symbolMatch.firstMatch(memberSymbol.toString());
final RegExpMatch? match = symbolMatch.firstMatch(memberSymbol.toString());
assert(match != null);
return match.namedGroup('name');
return match!.namedGroup('name')!;
}
final List<dynamic> positionalArguments;
final List<dynamic>? positionalArguments;
final bool acceptAny;
@override
......@@ -399,10 +396,10 @@ class Mock {
'${expected[count].memberName} instead.');
if (call.positionalArguments != null && !expected[count].acceptAny) {
int countArg = 0;
for (final dynamic arg in call.positionalArguments) {
expect(arg, equals(expected[count].positionalArguments[countArg]),
for (final dynamic arg in call.positionalArguments!) {
expect(arg, equals(expected[count].positionalArguments![countArg]),
reason: 'Failed at call $count. Positional argument $countArg to ${call.memberName} '
'not as expected. Expected ${expected[count].positionalArguments[countArg]} '
'not as expected. Expected ${expected[count].positionalArguments![countArg]} '
'and received $arg');
countArg++;
}
......
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