How to remove the second appbar in Flutter - 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:

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

route on tab leads to Black Screen

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

How to send setState to Second Page in Flutter?

I have a basic question about send setState
to Second Page in the same class as this method like
_GoToNextPage(){
Navigator.of(context).push(MaterialPageRoute(builder: (context) {...})
}
The problem is when I change background color in second page it doesn't
change color in the same page But it changes the color of The prime home page.
This is the full code...
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: SetStateToSecondPage(),
));
class SetStateToSecondPage extends StatefulWidget {
#override
_SetStateToSecondPageState createState() => _SetStateToSecondPageState();
}
class _SetStateToSecondPageState extends State<SetStateToSecondPage> {
Color color = Colors.deepPurpleAccent;
bool Switch = false;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: color,
appBar: AppBar(
title: Text('setState to Second Page ?'),
elevation: 0.0,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: () {
setState(() {
Switch = !Switch;
color = Switch ? Colors.white : Colors.green;
});
},
child: Text('Change Back GroundColor'),
),
RaisedButton(
onPressed: () {
_GoToNextPage(context);
},
child: Text('To Next Page..'),
),
],
),
),
);
}
//------------- This is second Page ----------//
_GoToNextPage(BuildContext context) {
return Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
backgroundColor: color,
body: Center(
child: RaisedButton(
onPressed: () {
setState(() {
color = Colors.red;
});
},
child: Text('Change Back GroundColor'),
),
),
);
}));
}
}
thanks
SetState is specific to the object you are in . and when you call it you notify the framework that the state has changed . so calling setState in _SetStateToSecondPageState will not affect Second Page so you need to create another StatefulWidget
class SecondPage extends StatefulWidget {
MaterialColor secondColor ;
SecondPage({this.secondColor});
#override
_SecondPageState createState() => new _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
backgroundColor: widget.secondColor,
body: Center(
child: RaisedButton(
onPressed: () {
setState(() {
widget.secondColor = Colors.amber;
});
},
child: Text('Change Back GroundColor'),
),
),
);
}
}
and when you call _GoToNextPage use the SecondPage constructor to change the color
_GoToNextPage(BuildContext context) {
return Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return SecondPage(
);
}));
}