route on tab leads to Black Screen - flutter

I defined the ontap method to navigate to SecondRoute class but it leads to the black screen.to resolve this issue I also replace the materialApp with Scaffold but didn't find luck
class FirstMain extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body:TabviewWidget(),
drawer: Drawer(
child: ListView(
children: <Widget>[
ListTile(
title: Text('Item 2'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
],
),
),
);
}
}
class SecondRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
I expected to open SecondRoute but appears black screen

Related

Navigator operation requested with a context that does not include a Navigator in flutter web

I was just put official Doc code for see how Navigation work in web(chrome). But when I click button I get an error->
Navigator operation requested with a context that does not include a Navigator.
code->
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: ElevatedButton(
child: Text('Open route'),
// Within the `FirstRoute` widget
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}),
),
),
);
}
}
class SecondRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: ElevatedButton(
// Within the SecondRoute widget
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
Thanks...

Flutter navigation by route name in statefull widget

i am trying to go on another page using navigation, but i am getting error;
Navigator operation requested with a context that does not include a
Navigator.
i am just trying to move on next page, i followed flutter documentations for this stateless widget but how to do with state full widget.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State createState() => new MyApp1();
}
class MyApp1 extends State<MyApp> {
List<Widget> _listSection = [];
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(),
],
),
),
),
);
}
Widget floatingButton() {
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/SecondScreen");
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
You should use the named route you created.
Widget floatingButton(BuildContext context) { // added context as a parameter
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/second"); // Changed this to use the named route
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
then use the following
body: Container(
child: Stack(
children: [
floatingButton(context),
],
),
),
The situation here is that the floatingButton() uses a context with the navigator to push the given page route. But the context used is provided in the parent Widget(MaterialApp) it self, which doesn't include a Navigator, hence the error.
So, Try this approach:
Separate the Home widget from the MaterialApp, like below:
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: HomePage(),
);
Create a stateless widget containing the Scaffold:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(),
],
),
),
);
}
}
Hope it helps. Let me know if this doesn't work.
You have made two mistakes because of which your code is not working:
You have used wrong route name. Replace /SecondScreen with /second
You have used wrong context. You can get Navigator only if your widget has MaterialApp as it's parent and here you are using context of MyApp1 so it is not working.
Following is a working code for your reference.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State createState() => new MyApp1();
}
class MyApp1 extends State<MyApp> {
List<Widget> _listSection = [];
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: AppContent(),
);
}
}
class AppContent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(context),
],
),
),
);
}
Widget floatingButton(BuildContext context) {
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/second");
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}

Switching pages in flutter

I have a side menu created using a Drawer Widget and I want to navigate between the pages in the side menu. I am using Navigator.push() to do so, but for some reason, the page won't change.
The items appear in the side menu, but when clicked on, the page remains the same. Does anyone know how I am misusing Navigator.push()?
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
return MaterialApp(
title: 'Grid App',
home: Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(
color: Colors.grey[700]
),
),
ListTile(
title: Text("First Page"),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new SecondPage()),);
},
),
],
),
),
),
);
}
}
class FirstPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: Center(
child: Text("You're on the first page!"),
),
);
}
}
class SecondPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Text("This is the second page"),
);
}
}
Just separate the MaterialApp with another screen. Simply you can right click on the Scaffold widget and select Extract Widget. Give the name to your widget and it will extract your code into another stateless widget.
copy paste this code to dartpad and run it
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
return MaterialApp(
title: 'Grid App',
home: NewApp(),
);
}
}
class NewApp extends StatelessWidget {
const NewApp({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(
color: Colors.grey[700]
),
),
ListTile(
title: Text("First Page"),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new SecondPage()),);
},
),
],
),
),
);
}
}
class FirstPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: Center(
child: Text("You're on the first page!"),
),
);
}
}
class SecondPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Text("This is the second page"),
);
}
}
The Navigator won't work if you're doing in under the MateriaApp context like you are using. Remove MaterialApp widget to main() or make another Widget for That.
Try this :
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(
color: Colors.grey[700]
),
),
ListTile(
title: Text("First Page"),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new SecondPage()),);
},
),
],
),
),
);
}
}
class FirstPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: Center(
child: Text("You're on the first page!"),
),
);
}
}
class SecondPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Text("This is the second page"),
);
}
}
Big problem here is using wrong context.
You can't use App context for Navigator. Take a try with Builder
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Grid App',
home: Builder(
builder: (context) => buildScaffold(context),
),
);
}
Scaffold buildScaffold(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Grip App'),
),
body: Center(
child: Text('Hello, this is the start page!'),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("Navigation"),
decoration: BoxDecoration(color: Colors.grey[700]),
),
ListTile(
title: Text("First Page"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FirstPage()),
);
},
),
ListTile(
title: new Text("Second Page"),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondPage()),
);
},
),
],
),
),
);
}
}
Quick Fix
void main() => runApp(MaterialApp(home: MyApp()));
Error You are facing
Your current code gives below error, you can see that in the console too
Error: The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
You can solve this by taking MaterialApp or Builder

How to go from one screen to another clearing all the previous screens from stack?

In my Flutter project, I have three screens - Screen0, Screen1, Screen2. Now, from the screen0 , I can go to the screen1 with a button click, then from screen1 we can go to screen2 with a button. In screen2, I have a button which I have used to go back to screen0. As Screen0 is the initial screen, I want to clear all the previous screens when I come back to Screen0 and don't want to have any back option like in this image-
And here's my code-
main.dart
import 'package:flutter/material.dart';
import 'screen0.dart';
import 'screen1.dart';
import 'screen2.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context)=> Screen0(),
'/first': (context)=> Screen1(),
'/second': (context)=> Screen2(),
},
);
}
}
I have set all the routes in my main.dart file. Then in the Screen0, I have a button to go to screen1 like below-
screen0.dart
import 'package:flutter/material.dart';
class Screen0 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text('Screen 0'),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text('Go to screen 1'),
onPressed: (){
Navigator.pushNamed(context, '/first');
},
),
],
),
),
);
}
}
In the screen1, I have a button to go to screen2-
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text('Screen 1'),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text('Go to screen 2'),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return Screen2();
})
);
},
),
],
),
),
);
}
}
Now, in the screen2, i have the button to go to screen0 -
class Screen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text('Screen 2'),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text('Go to screen 0'),
onPressed: (){
Navigator.pop(context, Screen2);
Navigator.pushNamed(context, '/');
},
),
],
),
),
);
}
}
I have tried some solution like using Navigator.pushAndRemoveUntil given in the below link-
Flutter - Navigate to a new screen, and clear all the previous screens
But this solution didn't work for me.
So, it would be nice if someone help me out this code to solve the problem.
use pushNamedAndRemoveUntil
for example
Navigator.of(context).pushNamedAndRemoveUntil('/screen4', (Route<dynamic> route) => false);

How to remove the second appbar in Flutter

I am trying to build a demo chat app with Flutter. After my main screen, I am using Navigator.push to go to the details screen.
Screenshot of problem:
build method of 1st screen:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Chat Thread App"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.pushNamed(context, '/settings');
},
)
],
),
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: new ChatThreadListCard(messageThreads: _messageThreadLists, user: _user,),
);
}
code of Navigator.push method:
Navigator.push(context, MaterialPageRoute(
builder: (context) => ChatDetailsScreen(threadModel: new ThreadModel(
user.id,
user.fullName,
user.pic,
"otherId",
"otherName",
"otherPic",
post.threadId
)
),
),);
build method of 2nd screen, where the problem is produced:
return Scaffold(
appBar: AppBar(
title: Text("Chat demo"),
),
body: WillPopScope(
child: isLoading
? Center(
child: CircularProgressIndicator(),
)
: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
SizedBox(
width: 300,
height: 300,
),
Column(
children: <Widget>[
buildChat(),
buildInput(),
],
)
],
),
onWillPop: onBackPress,
),
);
the problem turns out to be, i was creating a MaterialApp widget in scaffold's body. so, when the onTap method was called, the new screen was replaced insdie the MaterialApp's area. didnt replace the whole screen.
the trick was to remove the return new MaterialApp().
thanks everyone.
I'm guessing something isn't working right with where you're setting up the Material App?
app.dart:
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage());
}
}
home_page and second_page
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
#override
State createState() => HomePageState();
}
class HomePageState extends State<HomePage> with TickerProviderStateMixin {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Container(
child: Center(child: RaisedButton(child: Text('Forward'), onPressed: () async {
await Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
},)),
));
}
}
class SecondPage extends StatefulWidget {
#override
State createState() => SecondPageState();
}
class SecondPageState extends State<SecondPage> with TickerProviderStateMixin {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Container(
child: Center(child: RaisedButton(child: Text('Backward'), onPressed: () {
Navigator.of(context).pop();
},)),
));
}
}
Which produces: