An app has a BottomNavigationBarItem, which, as usual, enables switching between screens.
I wish to change the functionality of one screen, so that when the orientation is switched to landscape, a different screen is pushed onto the stack. The intention is that this new screen will overlay everything and have no navigation bar.
I tried the following:
@override
Widget build(BuildContext context) {
return OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
if (orientation == Orientation.portrait) {
return Column(
// regular content
}
} else {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => MyLandscapeViewWidget(module: widget.module)));
}
}
This will not work, because the else clause - triggered when in landscape mode - needs to return a widget.
What is the best solution?
Thanks
The issue with using Navigator.push is that it builds a new widget screen and disposes the previous one. What you are looking for is an OverlayEntry widget. OverlayEntry builds independently within its own widget tree and manages its own build lifecycle.
Here is an example demonstrating how to use OverlayEntry.
class MyOverlayScreen {
static OverlayEntry? _overlayEntry;
static void closeOverlayIfVisible() {
if (_overlayEntry == null) {
return;
}
_overlayEntry?.remove();
_overlayEntry = null;
}
static void show(BuildContext context) {
if (_overlayEntry != null) return;
_overlayEntry = OverlayEntry(
builder: (context) {
return const Material(
child:Center(
child: Text("Overlay Screen"),
));
},
);
Overlay.of(context).insert(_overlayEntry!);
}
}
You can now modify your code to show/hide the overlay widget.
OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (orientation == Orientation.landscape) {
MyOverlayScreen.show(context);
} else {
MyOverlayScreen.closeOverlayIfVisible();
}
});
...
I added PostFrameCallback to make sure the built first to eliminate the setState() or markNeedsBuild() error.
As a bonus, here is another usage example of OverlayEntry. It is used to maintain an active dialog screen even when navigating between screens https://dartpad.dev/?id=cbf43c2a652accbff41732d4489c7eb6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With