'No Overlay widget found when MaterialApp widget present
The following is a complete app and a bare-bones reproduction of an issue I am having. It has two screens - a home screen and a second screen. The pages share some common elements - in this case just a simple back navigation button. Instead of adding these elements to each screen manually I want to wrap each screen in a Screen widget from within the MaterialApp builder.
Why does the following work:
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: HomeScreen.routePath,
routes: {
HomeScreen.routePath: (_) => HomeScreen(),
SecondScreen.routePath: (_) => SecondScreen(),
},
builder: (context, child) => child ?? Container(),
);
}
}
class Screen extends StatelessWidget {
final Widget child;
const Screen(Widget widget) : child = widget;
@override
Widget build(BuildContext context) {
return Material(
child: Stack(children: [
child,
const Positioned(
top: 32,
left: 32,
child: BackButton(color: Colors.deepPurple),
),
]),
);
}
}
class HomeScreen extends StatelessWidget {
static const routePath = "/";
@override
Widget build(BuildContext context) => Screen(Center(
child: ElevatedButton(
child: const Text("Go to other screen"),
onPressed: () =>
Navigator.of(context).pushNamed(SecondScreen.routePath),
),
));
}
class SecondScreen extends StatelessWidget {
static const routePath = "/second";
@override
Widget build(BuildContext context) =>
const Screen(Center(child: Text("The second screen")));
}
But if I make these small changes and move the Screen widget up into the MaterialApp builder (see comments) I get an error.
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: HomeScreen.routePath,
routes: {
HomeScreen.routePath: (_) => HomeScreen(),
SecondScreen.routePath: (_) => SecondScreen(),
},
builder: (context, child) =>
Screen(child ?? Container()), // wrap the Screen widget here
);
}
}
class Screen extends StatelessWidget {
final Widget child;
const Screen(Widget widget) : child = widget;
@override
Widget build(BuildContext context) {
return Material(
child: Stack(children: [
child,
const Positioned(
top: 32,
left: 32,
child: BackButton(color: Colors.deepPurple),
),
]),
);
}
}
class HomeScreen extends StatelessWidget {
static const routePath = "/";
@override
Widget build(BuildContext context) => /* instead of here */ Center(
child: ElevatedButton(
child: const Text("Go to other screen"),
onPressed: () =>
Navigator.of(context).pushNamed(SecondScreen.routePath),
),
);
}
class SecondScreen extends StatelessWidget {
static const routePath = "/second";
@override
Widget build(BuildContext context) =>
const /* and instead of here */ Center(child: Text("The second screen"));
}
The error I receive is
No Overlay widget found.
Tooltip widgets require an Overlay widget ancestor for correct operation.
The most common way to add an Overlay to an application is to include a
MaterialApp or Navigator widget in the runApp() call.
Why does the MaterialApp widget not count as an ancestor to the Screen widget returned from the builder?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
