@@ -1636,6 +1636,7 @@ class _TimePickerInput extends StatefulWidget {
1636
1636
required this .helpText,
1637
1637
required this .autofocusHour,
1638
1638
required this .autofocusMinute,
1639
+ required this .emptyInitialTime,
1639
1640
this .restorationId,
1640
1641
});
1641
1642
@@ -1666,6 +1667,13 @@ class _TimePickerInput extends StatefulWidget {
1666
1667
/// from the surrounding [RestorationScope] using the provided restoration ID.
1667
1668
final String ? restorationId;
1668
1669
1670
+ /// If true and [TimePickerEntryMode.input] is used, hour and minute fields
1671
+ /// start empty instead of using [initialSelectedTime] .
1672
+ ///
1673
+ /// Useful when users prefer manual input without clearing pre-filled values.
1674
+ /// Ignored in dial mode.
1675
+ final bool emptyInitialTime;
1676
+
1669
1677
@override
1670
1678
_TimePickerInputState createState () => _TimePickerInputState ();
1671
1679
}
@@ -1851,6 +1859,7 @@ class _TimePickerInputState extends State<_TimePickerInput> with RestorationMixi
1851
1859
onSavedSubmitted: _handleHourSavedSubmitted,
1852
1860
onChanged: _handleHourChanged,
1853
1861
hourLabelText: widget.hourLabelText,
1862
+ emptyInitialTime: widget.emptyInitialTime,
1854
1863
),
1855
1864
),
1856
1865
if (! hourHasError.value && ! minuteHasError.value)
@@ -1885,6 +1894,7 @@ class _TimePickerInputState extends State<_TimePickerInput> with RestorationMixi
1885
1894
validator: _validateMinute,
1886
1895
onSavedSubmitted: _handleMinuteSavedSubmitted,
1887
1896
minuteLabelText: widget.minuteLabelText,
1897
+ emptyInitialTime: widget.emptyInitialTime,
1888
1898
),
1889
1899
),
1890
1900
if (! hourHasError.value && ! minuteHasError.value)
@@ -1935,6 +1945,7 @@ class _HourTextField extends StatelessWidget {
1935
1945
required this .onSavedSubmitted,
1936
1946
required this .onChanged,
1937
1947
required this .hourLabelText,
1948
+ required this .emptyInitialTime,
1938
1949
this .restorationId,
1939
1950
});
1940
1951
@@ -1947,6 +1958,7 @@ class _HourTextField extends StatelessWidget {
1947
1958
final ValueChanged <String > onChanged;
1948
1959
final String ? hourLabelText;
1949
1960
final String ? restorationId;
1961
+ final bool emptyInitialTime;
1950
1962
1951
1963
@override
1952
1964
Widget build (BuildContext context) {
@@ -1960,6 +1972,7 @@ class _HourTextField extends StatelessWidget {
1960
1972
semanticHintText: hourLabelText ?? MaterialLocalizations .of (context).timePickerHourLabel,
1961
1973
validator: validator,
1962
1974
onSavedSubmitted: onSavedSubmitted,
1975
+ emptyInitialTime: emptyInitialTime,
1963
1976
onChanged: onChanged,
1964
1977
);
1965
1978
}
@@ -1974,6 +1987,7 @@ class _MinuteTextField extends StatelessWidget {
1974
1987
required this .validator,
1975
1988
required this .onSavedSubmitted,
1976
1989
required this .minuteLabelText,
1990
+ required this .emptyInitialTime,
1977
1991
this .restorationId,
1978
1992
});
1979
1993
@@ -1985,6 +1999,7 @@ class _MinuteTextField extends StatelessWidget {
1985
1999
final ValueChanged <String ?> onSavedSubmitted;
1986
2000
final String ? minuteLabelText;
1987
2001
final String ? restorationId;
2002
+ final bool emptyInitialTime;
1988
2003
1989
2004
@override
1990
2005
Widget build (BuildContext context) {
@@ -1997,6 +2012,7 @@ class _MinuteTextField extends StatelessWidget {
1997
2012
style: style,
1998
2013
semanticHintText: minuteLabelText ?? MaterialLocalizations .of (context).timePickerMinuteLabel,
1999
2014
validator: validator,
2015
+ emptyInitialTime: emptyInitialTime,
2000
2016
onSavedSubmitted: onSavedSubmitted,
2001
2017
);
2002
2018
}
@@ -2013,6 +2029,7 @@ class _HourMinuteTextField extends StatefulWidget {
2013
2029
required this .validator,
2014
2030
required this .onSavedSubmitted,
2015
2031
this .restorationId,
2032
+ required this .emptyInitialTime,
2016
2033
this .onChanged,
2017
2034
});
2018
2035
@@ -2026,6 +2043,7 @@ class _HourMinuteTextField extends StatefulWidget {
2026
2043
final ValueChanged <String ?> onSavedSubmitted;
2027
2044
final ValueChanged <String >? onChanged;
2028
2045
final String ? restorationId;
2046
+ final bool emptyInitialTime;
2029
2047
2030
2048
@override
2031
2049
_HourMinuteTextFieldState createState () => _HourMinuteTextFieldState ();
@@ -2058,9 +2076,12 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
2058
2076
super .didChangeDependencies ();
2059
2077
// Only set the text value if it has not been populated with a localized
2060
2078
// version yet.
2079
+ // If emptyInitialTime is true, set it to an empty string to indicate no
2080
+ // initial time.
2061
2081
if (! controllerHasBeenSet.value) {
2062
2082
controllerHasBeenSet.value = true ;
2063
- controller.value.value = TextEditingValue (text: _formattedValue);
2083
+ final String initialTextValue = widget.emptyInitialTime ? '' : _formattedValue;
2084
+ controller.value.value = TextEditingValue (text: initialTextValue);
2064
2085
}
2065
2086
}
2066
2087
@@ -2113,7 +2134,8 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
2113
2134
).applyDefaults (inputDecorationTheme);
2114
2135
// Remove the hint text when focused because the centered cursor
2115
2136
// appears odd above the hint text.
2116
- final String ? hintText = focusNode.hasFocus ? null : _formattedValue;
2137
+ // Clear the hint text when emptyInitialTime is true.
2138
+ final String ? hintText = focusNode.hasFocus || widget.emptyInitialTime ? null : _formattedValue;
2117
2139
2118
2140
// Because the fill color is specified in both the inputDecorationTheme and
2119
2141
// the TimePickerTheme, if there's one in the user's input decoration theme,
@@ -2213,6 +2235,7 @@ class TimePickerDialog extends StatefulWidget {
2213
2235
this .onEntryModeChanged,
2214
2236
this .switchToInputEntryModeIcon,
2215
2237
this .switchToTimerEntryModeIcon,
2238
+ this .emptyInitialInput = false ,
2216
2239
});
2217
2240
2218
2241
/// The time initially selected when the dialog is shown.
@@ -2279,6 +2302,12 @@ class TimePickerDialog extends StatefulWidget {
2279
2302
/// {@macro flutter.material.time_picker.switchToTimerEntryModeIcon}
2280
2303
final Icon ? switchToTimerEntryModeIcon;
2281
2304
2305
+ /// If true and entry mode is [TimePickerEntryMode.input] , the hour and minute
2306
+ /// fields will be empty on start instead of pre-filled with [initialTime] .
2307
+ ///
2308
+ /// Has no effect in dial mode.
2309
+ final bool emptyInitialInput;
2310
+
2282
2311
@override
2283
2312
State <TimePickerDialog > createState () => _TimePickerDialogState ();
2284
2313
}
@@ -2617,6 +2646,7 @@ class _TimePickerDialogState extends State<TimePickerDialog> with RestorationMix
2617
2646
onEntryModeChanged: _handleEntryModeChanged,
2618
2647
switchToInputEntryModeIcon: widget.switchToInputEntryModeIcon,
2619
2648
switchToTimerEntryModeIcon: widget.switchToTimerEntryModeIcon,
2649
+ emptyInitialInput: widget.emptyInitialInput,
2620
2650
),
2621
2651
);
2622
2652
if (_entryMode.value != TimePickerEntryMode .input &&
@@ -2661,6 +2691,7 @@ class _TimePicker extends StatefulWidget {
2661
2691
this .onEntryModeChanged,
2662
2692
this .switchToInputEntryModeIcon,
2663
2693
this .switchToTimerEntryModeIcon,
2694
+ required this .emptyInitialInput,
2664
2695
});
2665
2696
2666
2697
/// Optionally provide your own text for the help text at the top of the
@@ -2735,6 +2766,9 @@ class _TimePicker extends StatefulWidget {
2735
2766
/// {@macro flutter.material.time_picker.switchToTimerEntryModeIcon}
2736
2767
final Icon ? switchToTimerEntryModeIcon;
2737
2768
2769
+ /// If true, input fields start empty in input mode.
2770
+ final bool emptyInitialInput;
2771
+
2738
2772
@override
2739
2773
State <_TimePicker > createState () => _TimePickerState ();
2740
2774
}
@@ -2996,6 +3030,7 @@ class _TimePickerState extends State<_TimePicker> with RestorationMixin {
2996
3030
autofocusHour: _autofocusHour.value,
2997
3031
autofocusMinute: _autofocusMinute.value,
2998
3032
restorationId: 'time_picker_input' ,
3033
+ emptyInitialTime: widget.emptyInitialInput,
2999
3034
),
3000
3035
],
3001
3036
);
@@ -3148,6 +3183,7 @@ Future<TimeOfDay?> showTimePicker({
3148
3183
Orientation ? orientation,
3149
3184
Icon ? switchToInputEntryModeIcon,
3150
3185
Icon ? switchToTimerEntryModeIcon,
3186
+ bool emptyInitialInput = false ,
3151
3187
}) async {
3152
3188
assert (debugCheckHasMaterialLocalizations (context));
3153
3189
@@ -3164,6 +3200,7 @@ Future<TimeOfDay?> showTimePicker({
3164
3200
onEntryModeChanged: onEntryModeChanged,
3165
3201
switchToInputEntryModeIcon: switchToInputEntryModeIcon,
3166
3202
switchToTimerEntryModeIcon: switchToTimerEntryModeIcon,
3203
+ emptyInitialInput: emptyInitialInput,
3167
3204
);
3168
3205
return showDialog <TimeOfDay >(
3169
3206
context: context,
0 commit comments