Deterministic Back Behavior
Define a single back policy so overlay dismissal and stack pops always happen in the same order. Decide the next action from the current overlay, stack, and tab state.
Overlay-first
Dismiss active overlays before popping page stacks. Only allow a page pop after no active overlay remains.
Root-aware
When stack length is one, delegate to parent behavior instead of force-pop. This preserves the parent or app-level back policy.
Tab-aware
In tab mode, move to the first tab at root before triggering app-level exit handling. Trigger exit handling only after the tab root has been reached.
Back Scope Pattern
Use DeclarativePagesBackScope for page stacks and tab callbacks for tab roots. Keep overlay dismissal, page popping, and root handling in that priority order.
Back Policy
DeclarativePagesBackScope
return DeclarativePagesBackScope(
pages: _pages,
popTopPage: _popTop,
isOverlayVisible: _overlay != null,
dismissOverlay: _dismissOverlay,
onBackAtRoot: _onBackAtRoot,
child: DeclarativePagesNavigator(
pages: _pages,
buildPage: _buildPage,
onPopTop: _popTop,
canPopTop: () => _overlay == null,
),
);
UX Stability
Keep one consistent order for all back events across every platform. This avoids confusion between Android system back and iOS gestures.
Previous
Declarative TabsNext
Anti-patterns