back page with flutter android back button - flutter

What codes should I use to go back to the page with the flutter android back button? I looked inside youtube, especially on Stackoverflow, but I couldn't get any results.

You can use WillPopScope
Here is example code:
class MyPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
// This function will handle back button
// When true, it's can back to previous page
// when false, back button will do nothing
return true;
},
child: Scaffold(
appBar: AppBar(
title: const Text('Flutter WillPopScope demo'),
),
body: Center(
child: Text('Hello world')
),
),
);
}
}

class Page2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new WillPopScope(
child: new Scaffold(
appBar: new AppBar(
title: new Text('Page 2'),
),
body: new Center(
child: new Text('PAGE 2'),
),
),
onWillPop: () async {
return false;
},
);
}
}
Future<T> pushPage<T>(BuildContext context, Widget page) {
return Navigator.of(context)
.push<T>(MaterialPageRoute(builder: (context) => page));
}
Can call the page like:
pushPage(context, Page2());

Related

How can i remove previous route if i navigate from drawer in flutter

When I navigate from drawer to any page and return back the drawer keeps open.
For example:
The drawer contains two-button and if I button one and then back, then second and then back.
Now if I press back button of android it will repeat all activities like in chrome.
Hope you get my point. If you need to know anything else from me. let me know
Hope this helps.
void main() {
runApp(
MaterialApp(
routes: {
"/": (context) => HomePage(),
"/settings": (context) => SettingsPage(),
},
),
);
}
String _currentRoute = "/";
Widget buildDrawer(context) {
return Drawer(
child: SafeArea(
child: Column(
children: <Widget>[
ListTile(
title: Text("Home"),
onTap: () => doRoute(context, '/'),
),
ListTile(
title: Text("Settings"),
onTap: () => doRoute(context, '/settings'),
),
],
),
),
);
}
void doRoute(BuildContext context, String name) {
if (_currentRoute != name)
Navigator.pushReplacementNamed(context, name);
else
Navigator.pop(context);
_currentRoute = name;
}
// Page 1 (HomePage)
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home")),
body: Container(color: Colors.blue.withOpacity(0.5)),
drawer: buildDrawer(context),
);
}
}
// Page 2 (SettingsPage)
class SettingsPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Settings")),
body: Container(color: Colors.orange.withOpacity(0.5)),
drawer: buildDrawer(context),
);
}
}

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

AppBar flickers when using Navigator.of(context).pushNamedAndRemoveUntil()

I'm tying to clear all of the previous routes after the user has logged on to my app. However, I'm having an issue with the following code in my Flutter app:
void clearRoutes()
{
//createLinks();
Navigator.of(context).pushNamedAndRemoveUntil('/my_home', (Route<dynamic> route) => false);
}
Widget build(BuildContext context)
{
WidgetsBinding.instance.addPostFrameCallback((_) => clearRoutes());
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("iWhiz Home"),
),
body: ListView.builder(
itemCount: links.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(links[index]),
);
}
),
);
}
The above code results in this issue:
The line of code that is giving me this issue is Navigator.of(context).pushNamedAndRemoveUntil('/my_home', (Route<dynamic> route) => false);
Can this issue be resolved?
I was able to find a solution. This is the code that was giving me a problem:
class Login extends StatelessWidget
{
void homePage(BuildContext context)
{
Navigator.pushNamed(context, "/my_home");
}
Widget build(BuildContext context)
{
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("Login"),
),
body: Center(
child:
Column(
children: [
Text("Welcome to the Login Page"),
ElevatedButton(
onPressed: ()
{
homePage(context);
},
child: Text("Login"),
),
],
)
),
);
}
}
class MyHome extends StatelessWidget
{
void removePreviousRoutes(BuildContext context)
{
//The problem code.
Navigator.of(context).pushNamedAndRemoveUntil('/my_home', (Route<dynamic> route) => false);
}
Widget build(BuildContext context)
{
WidgetsBinding.instance.addPostFrameCallback((_) => removePreviousRoutes(context));
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("My Home"),
),
body: Center(
child:
Text("Welcome to the Home Page"),
)
);
}
}
The initial page that would be displayed is Login. After the user clicks on 'Welcome to the Login Page' they would be directed to the MyHome page. The issue comes from Navigator.of(context).pushNamedAndRemoveUntil('/my_home', (Route<dynamic> route) => false); on the MyHome page.
Solution:
class Login extends StatelessWidget
{
void homePage(BuildContext context)
{
//The solution.
Navigator.pushNamed(context, "/my_home");
Navigator.of(context).pushNamedAndRemoveUntil('/my_home', (Route<dynamic> route) => false);
}
Widget build(BuildContext context)
{
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("Login"),
),
body: Center(
child:
Column(
children: [
Text("Welcome to the Login Page"),
ElevatedButton(
onPressed: ()
{
homePage(context);
},
child: Text("Login"),
),
],
)
),
);
}
}
class MyHome extends StatelessWidget
{
Widget build(BuildContext context)
{
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("My Home"),
),
body: Center(
child:
Text("Welcome to the Home Page"),
)
);
}
}
The solution was to push the new route AND remove all previous routes from Login, INSTEAD OF pushing the new route in Login and removing previous routes from Registration. After doing this, I no longer received the flickering issue.

Flutter navigation

Can someone explain why not printing efeioi when it is back from pageE?
Page A
Navigator.pushNamed(context, PageB.ROUTE).then((onValue) {
print("efeioi");
});
Page B
Navigator.of(context)
.pushReplacementNamed(PageC.ROUTE, arguments: onValue);
PageC
Navigator.pushNamed(context, PageD.ROUTE,
arguments: onValue);
PageD
Navigator.pop(context); // back to Page C
Page C
Navigator.pushNamed(context, PageE.ROUTE,
arguments: onValue);
Page E
Navigator.of(context).popUntil(ModalRoute.withName(PageA.ROUTE));
I can't use Navigator.pop in Page E because it will back to Page C!
I have uploaded full code here
https://github.com/tony123S/navigation
As per your requirement I have implemented as below
main.dart
initState : this will be called when you navigate from E to A
refreshPage : it will not called as you already popped before returning to A Page
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,
),
home: A(),
routes: <String, WidgetBuilder>{
'/A': (BuildContext context) => new A(),
'/B': (BuildContext context) => new B(),
'/C': (BuildContext context) => new C(),
'/D': (BuildContext context) => new D(),
'/E': (BuildContext context) => new E(),
},
);
}
}
class A extends StatefulWidget {
#override
_FirstRouteState createState() => _FirstRouteState();
}
class _FirstRouteState extends State<A> {
final String fromPage;
_FirstRouteState({Key key, #required this.fromPage});
#override
void initState() {
// TODO: implement initState
super.initState();
print("Called askdfjaksdfj");
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Page A'),
),
body: Center(
child: RaisedButton(
child: Text('Open B'),
onPressed: () {
// Navigate to second route when tapped.
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => B()),
// );
Navigator.push(
context,
MaterialPageRoute(builder: (context) => B()),
).then((res) => refreshPage());
},
),
),
);
}
refreshPage() {
print("refresh page is called");
}
}
class B extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("B Page"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to first route when tapped.
Navigator.of(context).pushNamed(
"/C",
);
},
child: Text('Go to C'),
),
),
);
}
}
class C extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("C Page"),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
// Navigate back to first route when tapped.
Navigator.pushNamed(
context,
"/D",
);
},
child: Text('Go to D'),
),
RaisedButton(
onPressed: () {
// Navigate back to first route when tapped.
Navigator.pushNamed(
context,
"/E",
);
},
child: Text('Go to E'),
),
],
),
),
);
}
}
class D extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("D Page"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to first route when tapped.
Navigator.pop(context);
},
child: Text('Go back to C'),
),
),
);
}
}
class E extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("E Page"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigator.pop(context);
// Navigator.of(context).pushNamed("/A");
// Navigator.of(context).popUntil(ModalRoute.withName('/A'));
Navigator.of(context)
.pushNamedAndRemoveUntil('/A', (Route<dynamic> route) => false,);
},
child: Text('Go to A'),
),
),
);
}
}
Please run code for better understanding and reply if you found any difficulty

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: