How to Fix Flutter TimePicker Appearing Behind Stepper Widget
Understanding the Issue
When building multi-step forms in Flutter using the Stepper widget, you might encounter a rendering glitch where calling showTimePicker (or showDatePicker) renders the picker dialog behind the stepper layout. As a result, the dialog becomes unclickable, unresponsive, and fails to dismiss when switching steps.
Why Does This Happen?
This behavior is caused by context and navigator overlay hierarchies in Flutter. By default, showTimePicker attempts to look up the nearest Navigator in the widget tree using the provided BuildContext. If your Stepper or step content operates inside a nested navigator or custom overlay stack, the picker dialog gets rendered inside that local sub-tree layer instead of the global application screen overlay.
The Fix: Use useRootNavigator: true
The simplest and most effective solution is to explicitly instruct showTimePicker to use the root navigator. Setting useRootNavigator: true pushes the modal dialog onto the top-most overlay layer, placing it squarely in front of the Stepper widget and all other UI elements.
Updated Code Solution
Modify your ElevatedButton's onPressed handler by adding useRootNavigator: true to the showTimePicker call:
ElevatedButton(
child: const Text("Choose Time"),
onPressed: () async {
final TimeOfDay? timeOfDay = await showTimePicker(
context: context,
initialTime: selectedTime,
initialEntryMode: TimePickerEntryMode.dial,
useRootNavigator: true, // Fixes z-index layering issues
);
if (timeOfDay != null) {
setState(() {
selectedTime = timeOfDay;
});
}
},
)Additional Troubleshooting Tips
- Date Pickers: If you face the same layer issue with
showDatePicker, passuseRootNavigator: truethere as well. - Valid Context: Ensure that the
contextpassed to the picker function is valid and actively mounted. Wrapping your step content inside aBuilderwidget can help if you still experience context lookup issues.