NavigatorResizable class
A thin wrapper around Navigator that visually resizes the child navigator to match the size of the content displayed in the current route.
This widget is functionally similar to combining OverflowBox and ClipRect, but it is specifically designed for this use case. It adjusts its size, hit test area, and painting area to align with the size of the widget displayed by the child navigator's current route. The navigator itself can overflow this widget, maintaining its size as determined by the parent constraints unless those constraints change. This helps minimize unnecessary layout operations for the navigator and its routes.
Routes and Pages
The NavigatorResizable can respect the content size of a route only if the route mix-ins the ObservableRouteMixin and its content is wrapped in a ResizableNavigatorRouteContentBoundary. This is especially important during route transitions, as the NavigatorResizable can animate its size in sync with the transition animation only when both the current route and the next route satisfy these requirements. Otherwise, the size remains unchanged before and after the transition.
For convenience, the following built-in route and page classes are provided, all of which satisfy the requirements of NavigatorResizable:
- ResizableMaterialPageRoute: A replacement for MaterialPageRoute.
- ResizableMaterialPage: A replacement for MaterialPage.
- ResizablePageRouteBuilder: A replacement for PageRouteBuilder.
- ResizablePageRoutePageBuilder: Similar to ResizablePageRouteBuilder, but creates a Page.
Note that the child navigator and its routes are constrained by the constraints imposed by the parent widget of the NavigatorResizable. To ensure that the route content fills the entire available space, the easiest way is to set the content widget's width or height to double.infinity.
ResizableMaterialPageRoute(
builder: (context) {
return Container(
color: Colors.while,
width: double.infinity,
height: double.infinity,
);
},
);
For more advanced use cases, you can create a custom route compatible with NavigatorResizable by mixing in the ObservableRouteMixin and returning a ResizableNavigatorRouteContentBoundary in ModalRoute.buildPage.
class CustomResizableRoute<T> extends ModalRoute<T>
with ObservableRouteMixin<T>{
CustomResizableRoute({
required super.builder,
...
});
@override
Widget buildContent(BuildContext context) {
return ResizableNavigatorRouteContentBoundary(
child: builder(context),
);
}
}
Caveats
- Avoid wrapping the navigator in widgets that add additional space (e.g., Padding). Zero-size widgets, such as GestureDetector or InheritedWidget, are acceptable.
- Do not place NavigatorResizable inside a widget with a tight constraint, as this forces NavigatorResizable to ignore the size of the current route's content and adopt the size dictated by the constraints. In such cases, an assertion error will be thrown. Typically, Center and Align are good choices for the parent widget.
- The initial route of the child navigator must satisfy the requirements of NavigatorResizable. Otherwise, NavigatorResizable will be unable to determine the initial size and will throw an assertion error.
Example
The following example demonstrates a resizable window centered within a Scaffold that can display multiple pages:
Navigator nestedNavigator;
return Scaffold(
body: Center(
child: Material(
color: Colors.white,
child: NavigatorResizable(
child: nestedNavigator,
),
),
),
);
You can use any standard navigation methods, such as Navigator.push, Navigator.pop, named routes, and the Pages API, with NavigatorResizable as you would with a regular Navigator:
Navigator.push(
context,
ResizableMaterialPageRoute(
builder: (context) {
return Container(
color: Colors.red,
width: 300,
height: 300,
);
},
),
);
For more practical examples, refer to the /example directory.
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- NavigatorResizable
Constructors
-
Creates a thin wrapper around Navigator that visually resizes
the
childnavigator to match the size of the content displayed in the current route.const
Properties
- child → Widget
-
The Navigator for which the visual resizing should be applied.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- interpolationCurve → Curve
-
The Curve used for interpolating the size of this widget
during a route transition animation.
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< NavigatorResizable> -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited