I'm trying to make a card clickable and navigate to another page 'forecastWeather.dart'. But I can't seem to figure out how I can fix the error I'm getting. The error message says
Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.
I'm using a TabBarView with two tabs and one contains a card which should be clickable and navigate to another page 'forecastWeather.dart'. Please help!
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
WeatherData weatherData = WeatherData();
bool isLoading = false;
@override
void initState() {
super.initState();
loadWeather();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Weather App',
theme: ThemeData(
primaryColor: Colors.lime.shade200,
),
home: DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.deepOrange.shade200,
title: Text('Weather App', style: GoogleFonts.roboto()),
bottom: const TabBar(
indicatorColor: Colors.white70,
indicatorWeight: 5.0,
labelColor: Colors.white,
labelPadding: EdgeInsets.only(top: 10.0),
unselectedLabelColor: Colors.grey,
tabs: [
Tab(
icon: FaIcon(
FontAwesomeIcons.solidSun,
color: Colors.orange,
),
),
Tab(
icon: Icon(
Icons.favorite,
color: Colors.pink,
)),
]),
),
body: Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Colors.red.shade300, Colors.white],
),
),
child: TabBarView(
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ForecastWeather(),
),
);
},
child: Card(
color: Colors.transparent,
child: Padding(
padding: const EdgeInsets.only(top: 90.0),
child: Weather(weather: weatherData),
),
),
),
SecondTab()
],
)),
]),
),
),
);
}
What am I doing wrong that card is not working as it's supposed to? I'm using InkWell to have the card navigate to another page once clicked.
CodePudding user response:
In order to get use navigator.push
, you must pass the context of your widget and have a MaterialApp
somewhere in your tree, you do both, so the code should work, but it doesn't.
The reason is simple, the context you are passing is outdated, you are first creating the context when the build method begins, at that point, there is no material app, then you add a material app, but the context already exists, so the context you are passing when calling Navigator.push(context ...
has no MaterialApp
.
A possible fix is to use the Builder
widget to make a new context after you create the MaterialApp
widget:
@override
Widget build(BuildContext context) {
// context has no material app.
return MaterialApp(
home: Builder(
builder: (context) {
// this context does have a material app and is safe to use.
return DefaultTabController( ... );
}
),
);
}
Another fix is to move the code into a new widget with it's own context:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainPage(),
);
}
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// this context was created after the material app.
return DefaultTabController(...);
}
}
CodePudding user response:
i suggest you to use get: ^4.6.1
package.
with this package you just need to use this for any navigation:
Get.to(ForecastWeather());
this package have so other features read its document here [1]: https://pub.dev/packages/get