Flutter navigation by route name in statefull widget - flutter

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!'),
),
),
);
}
}

Related

flutter int got to zero

I have a screen with a one button and anotherone with a Container to show a number. I declared a variable in the StatlessWidget class. The button adds 1 to the variable , however after leaving the Class with the container und return to it, I noticed the widgets get updated and my variable loses its value. I have tried initializing it in initState() but it still loses it's value.
import 'package:flutter/material.dart';
import 'package:generator/route_generator.dart';
import 'package:generator/main.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/menu',
onGenerateRoute: RouteGenerator.generateRoute,
);
}
}
class Menu extends StatelessWidget {
int data = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/second', arguments: data);
},
child: Text('go to the second'),
),
],
),
));
}
}
class FirstPage extends StatelessWidget {
int data = 0;
void eins() {
data = data + 25;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
data.toString(),
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/second', arguments: data);
},
child: Text('go to the second'),
),
RaisedButton(
child: Text('25'),
onPressed: eins,
)
],
),
));
}
}
class SecondPage extends StatelessWidget {
int data = 0;
SecondPage({Key key, #required this.data}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
data.toString(),
style: TextStyle(fontSize: 20),
),
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/first');
},
child: Text('go to the first'),
),
],
),
));
}
}
another class
import 'package:flutter/material.dart';
import 'package:generator/main.dart';
import './main.dart';
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case '/first':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/third':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/menu':
return MaterialPageRoute(
builder: (_) => Menu(),
);
case '/second':
// if (args is int) {
return MaterialPageRoute(
builder: (_) => SecondPage(
data: args,
),
);
//}
// return _errorRoute();
//default:
//return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(builder: (_) {
return Scaffold(
appBar: AppBar(
title: Text('Error'),
),
body: Center(
child: Text('ERROR'),
),
);
});
}
}
The first thing that is weird about your program is that you want to preserve state, in your case a counter variable, but to do that, you select a StatelessWidget. At the very least you will need a StatefulWidget. It's in the name already.
That said, it's not that easy, you may want to look up the different approaches to state management in Flutter: https://flutter.dev/docs/development/data-and-backend/state-mgmt/options
To expand on what #nvoigt said, pick a state management solution instead of passing around arguments from page to page. This way you can keep your widgets stateless, which is preferred but not possible to do what you want to do without a state management solution.
Here's a quick way using GetX state management. This can be done using Provider, RiverPod, Bloc/Cubit...pick your poison.
Here's a new controller class with your data and logic.
class DataController extends GetxController {
int data = 0;
void eins() {
data += 25;
update();
}
}
Then a couple small changes to the rest of your good and you're good to go.
void main() {
Get.put(DataController()); // initializing your controller
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/menu',
onGenerateRoute: RouteGenerator.generateRoute,
);
}
}
class Menu extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/second');
},
child: Text('go to the second'),
),
],
),
));
}
}
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final controller = Get.find<DataController>(); // finding controller
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GetBuilder<DataController>( // wrap your text in GetBuilder to display variabe
builder: (_) {
return Text(
controller.data.toString(), // accessing variable via controller
);
},
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/second');
},
child: Text('go to the second'),
),
RaisedButton(
child: Text('25'),
onPressed: () {
controller.eins(); // accessing function via controller
}),
],
),
));
}
}
class SecondPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final controller = Get.find<DataController>(); // finding same instance of controller on new page
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GetBuilder<DataController>(
builder: (_) {
return Text(
controller.data.toString(),
);
},
),
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/first');
},
child: Text('go to the first'),
),
],
),
));
}
}
// no longer need to pass anything in your router below
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/first':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/third':
return MaterialPageRoute(
builder: (_) => FirstPage(),
);
case '/menu':
return MaterialPageRoute(
builder: (_) => Menu(),
);
case '/second':
// if (args is int) {
return MaterialPageRoute(
builder: (_) => SecondPage(),
);
//}
// return _errorRoute();
//default:
//return _errorRoute();
}
}

Flutter navigator not working : OnPress not showing second screen

This is my code don't know why its not moving to screen 2 on button press:
Am beginner in dart/flutter please help. On press of button it's not showing screen2
//main.dart
import 'package:flutter/material.dart';
import 'screen_1.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Screen1(),
);
}
}
//screen_1.dart
import 'package:flutter/material.dart';
import 'screen_2.dart';
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen 1'),
),
body: Container(
child: Center(
child: RaisedButton(
color: Colors.pink,
child: Text(
'Go to Screen 2',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return Screen2();
},
),
);
},
),
),
),
);
}
}
//screen_2.dart
import 'package:flutter/material.dart';
class Screen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text('Screen 2'),
),
body: Center(
child: RaisedButton(
color: Colors.blue,
child: Text('Go Back To Screen 1'),
onPressed: () {},
),
),
);
}
}
onPressed of Screen1 class should show Screen2 but it's not happening.
I tried this and it does move to Screen2:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Screen1(),
);
}
}
//screen_1.dart
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen 1'),
),
body: Container(
child: Center(
child: RaisedButton(
color: Colors.pink,
child: Text(
'Go to Screen 2',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return Screen2();
},
),
);
},
),
),
),
);
}
}
//screen_2.dart
class Screen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text('Screen 2'),
),
body: Center(
child: RaisedButton(
color: Colors.blue,
child: Text('Go Back To Screen 1'),
onPressed: () {},
),
),
);
}
}
This may be because StatelessWidget is part of material.dart yet you failed to import it in the first dart file.

Refresh listView from PopUntil

Just wonder if I use this code to return PageA from PageD, which function will it get called in PageA?
PageD
Navigator.of(context).popUntil(ModalRoute.withName(PageA.ROUTE));
I would like to make the listView on PageA refreshed once it is back from PageD, but I don't know how to achieve it.
I added a then in PageA, but it is not printing anything.
Navigator.pushNamed(context, PageB.ROUTE).then((onValue) {
print("call from Page4");
_refreshListView();
});
Edit
My project flow is Page A > Page B > Page C > Page D > page A.
All you need to do is return data when you pop PageD and await the data when you push.
This code should help:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/' : (context) => PageA(),
'/go': (context) => PageD()
},
);
}
}
class PageA extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
),
body: Center(
child: ListView(
children: <Widget>[
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: Icon(Icons.forward),
),
);
}
_navigateAndDisplaySelection(BuildContext context) async {
final result = await Navigator.pushNamed(
context,
'/go'
);
if(result){
print(result);
//call the refresh ListView here
_refreshListView();
}
}
}
class PageD extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page D"),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white,),
onPressed: (){
Navigator.pop(context, true);
},
)
),
body: Center(
child: Text("Press back!!"),
),
);
}
}
As to what you explained in the comments... you have to pass arguments from Page D to A when navigating.
Hope this helps.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => PageA(),
'/b': (context) => PageB(),
'/c': (context) => PageC(),
'/d': (context) => PageD()
},
);
}
}
class PageA extends StatelessWidget {
#override
Widget build(BuildContext context) {
final bool shouldRefresh = ModalRoute.of(context).settings.arguments;
if (shouldRefresh != null) {
print(shouldRefresh);
//call the refresh ListView here
_refreshListView();
}
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
),
body: Center(
child: ListView(
children: <Widget>[],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/b');
},
child: Icon(Icons.forward),
),
);
}
}
class PageB extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page B"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.forward),
onPressed: () {
Navigator.pushNamed(context, '/c');
},
),
);
}
}
class PageC extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page C"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.forward),
onPressed: () {
Navigator.pushNamed(context, '/d');
},
),
);
}
}
class PageD extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Page D"),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {
Navigator.pushNamed(context, '/', arguments: true);
},
)),
body: Center(
child: Text("Press back!!"),
),
);
}
}
If you want to go to Page D when you press back in Page A then use this
class PageA extends StatelessWidget {
#override
Widget build(BuildContext context) {
final bool shouldRefresh = ModalRoute.of(context).settings.arguments;
print(shouldRefresh);
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {
Navigator.pushNamed(
context,
'/d',
arguments: true
);
},
),
),
body: Center(
child: ListView(
children: <Widget>[
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/b');
},
child: Icon(Icons.forward),
),
);
}
}

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 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: