Flutter Retrieve Value from TextField - flutter

I'm trying to get the value from the TextField then compare it to a string = '123'
If the value = '123' then alert 'Successful!' or else alert 'Failed!'
Here is my code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}
class MyCustomForm extends StatefulWidget {
#override
_MyCustomFormState createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
TextEditingController myController = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: myController,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if(myController == '123')
{
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Successful!'),
);
},
);
}
else
{
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Failed!'),
);
},
);
}
},
child: Icon(Icons.text_fields),
),
);
}
}
My code always shows failed even I entered '123'. Can someone help me to figure out what I did wrong here? Thank you

To access the text inside a TextField Controller, you need to use myController.text, the myController is just a controller itself so you can't compare it to a String like that.
So, you should change this line
if(myController == '123')
into this
if(myController.text == '123')

Related

How can i pass parameters in flutter if the user goes back with the arrow?

I know that if you had a raiseButton you can do
Navigation .... .pop(value);
But what happens if the user goes back and i want to update the value, because result will be null
Navigator.push(context, MaterialPageRoute(builder: (context) {
return GalleryClassOne();
})).then((result) {
if (result != null) {
setState(() {
imagesClas1 = result;
});
}
});
You can override the back button behavior with WillPopScope widget. And manually pop with the data you need. Here is the code:
import 'package:flutter/material.dart';
void main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Navigator(
onGenerateRoute: (settings) => MaterialPageRoute(
builder: (context) => MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void _onButtonPressed() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => OtherPage()))
.then((value) {
print("returned: $value");
if (value != null) {
setState(() {
// ...
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Demo")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text("Open another screen"),
onPressed: _onButtonPressed),
],
),
),
);
}
}
class OtherPage extends StatelessWidget {
OtherPage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
// here you can return anything you need ...
Navigator.of(context).pop("my value");
// cancel default behaviour
return false;
},
child: Scaffold(
appBar: AppBar(title: Text("Other page")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Click on return button'),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
You should return your data at a variable like this
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SelectionScreen()),
);
The result variable has your data.
for more info, have a look at the docs

How to temporarily unsubscribe to Stream after Navigator.of(context).push(....)?

Scenario : There are two pages. PhonePage and OtpPage . User inputs phone number in PhonePage and gets redirected to OtpPage to verify the OTP sent to him.
Problem: The API that talks to the server uses a StreamController.broadcast() to tell the app the response of the request. This Stream is shared by both PhonePage and OtpPage and produces events. The two pages listen to the stream and decide what to do based on the event.
However, after Navigator.push(), the old page is still listening to the stream. Thus when user in OtpPage taps the resend button, Navigator.push in PhonePage is still called although it should not.
Question What does Flutter has to deal with such scenario ? I tried onDispose() but it does not get called.
I would appreciate if you could also explain why onDispose is not called too.
Code: this is the code to reproduce the scenario. You can just paste it on your IDE or DartPad https://dartpad.dev/flutter (Note: When you go to OtpPage and some text on the text field, the click on resend button. Notice how a new OtpPage Widget is added on top the Navigator tree. That's the unwanted behaviour )
import 'dart:async';
import 'package:flutter/material.dart';
final fakeApiResponse = StreamController.broadcast();
void main() => runApp(MyApp(),);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PhoneNumber(),
);
}
}
class PhoneNumber extends StatefulWidget {
#override
_PhoneNumberState createState() => _PhoneNumberState();
}
class _PhoneNumberState extends State<PhoneNumber> {
StreamSubscription apiEventListner;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Enter your phone number'),
RaisedButton(
child: Text('Send OTP'),
onPressed: () {
fakeApiResponse.add('OTP Sent');
},
),
],
),
);
}
#override
void initState() {
super.initState();
apiEventListner = fakeApiResponse.stream.listen((data) {
if (data == 'OTP Sent') {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => VerifyOtp(),
),
);
}
});
}
#override
void dispose() {
super.dispose();
apiEventListner.cancel();
}
}
class VerifyOtp extends StatefulWidget {
#override
_VerifyOtpState createState() => _VerifyOtpState();
}
class _VerifyOtpState extends State<VerifyOtp> {
StreamSubscription apiEventListner;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextField(
decoration: InputDecoration(hintText: 'Enter OTP Here'),
),
RaisedButton(
child: Text("Verify"),
onPressed: () {
fakeApiResponse.add('OTP Verified');
},
),
RaisedButton(
child: Text("Didn't get the code? Resend OTP"),
onPressed: () {
fakeApiResponse.add('OTP Sent');
},
),
],
),
);
}
#override
void initState() {
super.initState();
apiEventListner = fakeApiResponse.stream.listen((data) {
if (data == 'OTP Sent') {
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("OTP Resent"),
content: Text("Enter new OTP"),
);
},
);
}else if (data == 'OTP Verified'){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>SuccessPage()));
}
});
}
#override
void dispose() {
super.dispose();
apiEventListner.cancel();
}
}
class SuccessPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('SUCCESS!'),
),
);
}
}
I found the solution. I am going to post anyways it here in case it might be helpful for someone else.
The trick is to detect the current active route and return if the current widget is not the current route inside the listeners of the Streams.
Flutter has an API called ModalRoute route = ModalRoute.of(context); then route.isCurrent will be true if the current widget is the current route.
Then you have to add this check in both pages.
The final working code would be:
import 'dart:async';
import 'package:flutter/material.dart';
final fakeApiResponse = StreamController.broadcast();
void main() => runApp(
MyApp(),
);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PhoneNumber(),
);
}
}
class PhoneNumber extends StatefulWidget {
#override
_PhoneNumberState createState() => _PhoneNumberState();
}
class _PhoneNumberState extends State<PhoneNumber> {
StreamSubscription apiEventListner;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Enter your phone number'),
RaisedButton(
child: Text('Send OTP'),
onPressed: () {
fakeApiResponse.add('OTP Sent');
},
),
],
),
);
}
#override
void initState() {
super.initState();
apiEventListner = fakeApiResponse.stream.listen((data) {
ModalRoute route = ModalRoute.of(context);
String name = route?.settings?.name;
print("Phone page isCurrent: ${route?.isCurrent} isFirst: ${route?.isFirst} active: ${route?.isActive} $name");
if (route?.isCurrent != null && !route.isCurrent) {
return;
}
if (data == 'OTP Sent') {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => VerifyOtp(),
),
);
}
});
}
#override
void dispose() {
super.dispose();
apiEventListner.cancel();
}
}
class VerifyOtp extends StatefulWidget {
#override
_VerifyOtpState createState() => _VerifyOtpState();
}
class _VerifyOtpState extends State<VerifyOtp> {
StreamSubscription apiEventListner;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextField(
decoration: InputDecoration(hintText: 'Enter OTP Here'),
),
RaisedButton(
child: Text("Verify"),
onPressed: () {
fakeApiResponse.add('OTP Verified');
},
),
RaisedButton(
child: Text("Didn't get the code? Resend OTP"),
onPressed: () {
fakeApiResponse.add('OTP Sent');
},
),
],
),
);
}
#override
void initState() {
super.initState();
apiEventListner = fakeApiResponse.stream.listen((data) {
ModalRoute route = ModalRoute.of(context);
String name = route?.settings?.name;
print("OTP page isCurrent: ${route?.isCurrent} isFirst: ${route?.isFirst} active: ${route?.isActive} $name");
if (route?.isCurrent != null && !route.isCurrent) {
return;
}
if (data == 'OTP Sent') {
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("OTP Resent"),
content: Text("Enter new OTP"),
);
},
);
} else if (data == 'OTP Verified') {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => SuccessPage()));
}
});
}
#override
void dispose() {
super.dispose();
apiEventListner.cancel();
}
}
class SuccessPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('SUCCESS!'),
),
);
}
}

Flutter - Why setstate doesn't work on popup?

I want to change the text on popup with user interaction but it is not changing. I've tried navigator.pop(context) and relaunch show method. It correctly work but is it a correct way? And can I change value on the popup without Navigator.pop. Why doesn't it work?
Here is my code.
import 'package:flutter/material.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
void main() => runApp(RatelApp());
class RatelApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('RFlutter Alert by Ratel'),
),
body: Home(),
),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String val = "Deneme";
showAlertDialog(BuildContext context, Function onPressed) {
// set up the button
Widget okButton = FlatButton(
child: Text(val),
onPressed: onPressed,
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("My title"),
content: Text("This is my message."),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
#override
Widget build(BuildContext context) {
return Container(
child: RaisedButton(
child: Text("Show Popup"),
onPressed: () {
showAlertDialog(context, (){
setState(() {
val = "changed";
});
});
},
),
);
}
}
Dialogs are usually stateless and are also not a part of the state of the calling Widget so calling that setState method isn't doing anything for the dialog. To make a dialog that can have changing contents use a StatefulBuilder.
The docs have an example that shows how to use it in a dialog just like in your application.
Docs example:
await showDialog<void>(
context: context,
builder: (BuildContext context) {
int selectedRadio = 0;
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(4, (int index) {
return Radio<int>(
value: index,
groupValue: selectedRadio,
onChanged: (int value) {
setState(() => selectedRadio = value);
},
);
}),
);
},
),
);
},
);
You need to wrap your AlertDialog with StatefulBuilder widget.

Showing a dialog that is in another file in flutter app

I'm trying to show a dialog box that is in another file in a StatefullWidget but when I call its function nothing is happening.
The reason I want to do this is because there is too much nesting of code in my code so I want to keep things simple and clean.
Below is the dialog.dart file.
import 'package:flutter/material.dart';
class PersonDetailsDialog extends StatefulWidget {
PersonDetailsDialog({Key key}) : super(key: key);
#override
_PersonDetailsDialogState createState() {
return _PersonDetailsDialogState();
}
}
class _PersonDetailsDialogState extends State<PersonDetailsDialog> {
#override
Widget build(BuildContext context) {
Future<void> _neverSatisfied() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Rewind and remember'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('You will never be satisfied.'),
Text('You\’re like me. I’m never satisfied.'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Regret'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
Below is the main.dart file.
mport 'package:flutter/material.dart';
import 'package:practical_0/homepage.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue
),
home: Homepage(),
);
}
}
Below is homepage.dart file where I'm trying to show the dialog when the user clicks RaisedButton but nothing happens.
import 'package:flutter/material.dart';
class Homepage extends StatelessWidget {
final double heightFactor = 600/896;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: RaisedButton(
onPressed: PersonDetailsDialog(), // show dialog
),
),
);
}
}
You have to use ShowDialog Where You want to show dialog.
I hope that following example clear your idea.
class Delete extends StatefulWidget {
#override
_DeleteState createState() => _DeleteState();
}
class _DeleteState extends State<Delete> {
BuildContext parent, child;
#override
Widget build(BuildContext context) => Scaffold(
body: Container(
child: Center(
child: RaisedButton(
onPressed: () {
showDialog(
context: context,
barrierDismissible: false,
child: PersonDetailsDialog());
}, // show dialog
),
),
),
);
}
class PersonDetailsDialog extends StatefulWidget {
PersonDetailsDialog({Key key}) : super(key: key);
#override
_PersonDetailsDialogState createState() {
return _PersonDetailsDialogState();
}
}
class _PersonDetailsDialogState extends State<PersonDetailsDialog> {
#override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Rewind and remember'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('You will never be satisfied.'),
Text('You\’re like me. I’m never satisfied.'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Regret'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
}
}
Here is an example:
Show dialog is an async function
child: RaisedButton(
onPressed: () async{
final result = await showDialog(
context: context,
builder: (_) => AlertWidget(),
);
return result;
},

Flutter Back button with return data

I have an interface with two buttons that pop and return true or false, like so:
onPressed: () => Navigator.pop(context, false)
I need to adapt the back button in the appbar, so it pops and also returns false. Is there a way to accomplish this?
The easier way is to wrap the body in WillPopScope, in this way it will work with the Back Button on the Top AND the Android Back Button on the Bottom.
Here an example where both back buttons return false:
final return = Navigator.of(context).push(MaterialPageRoute<bool>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New Page"),
),
body: WillPopScope(
onWillPop: () async {
Navigator.pop(context, false);
return false;
},
child: newPageStuff(),
),
);
},
));
In the other answers they suggested to use:
leading: BackButton(...)
I found that this works on with the Back Button on the Top and not with the Android one.
I include anyway an example:
final return = Navigator.of(context).push(MaterialPageRoute<bool>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: BackButton(
onPressed: () => Navigator.pop(context, false),
),
title: Text("New Page"),
),
body: newPageStuff(),
);
},
));
The default BackButton takes over the leading property of your AppBar so all you need to do is to override the leading property with your custom back button, for example:
leading: IconButton(
icon: Icon(Icons.chevron_left),
onPressed: () => Navigator.pop(context, false),
),
This may help and work for you
1st screen
void goToSecondScreen()async {
var result = await Navigator.push(_context, new MaterialPageRoute(
builder: (BuildContext context) => new SecondScreen(context),
fullscreenDialog: true,)
);
Scaffold.of(_context).showSnackBar(SnackBar(content: Text("$result"),duration: Duration(seconds: 3),));
}
2nd screen
Navigator.pop(context, "Hello world");
To pop the data and pass data back on navigation, you need to use .then() from screen 1. Below is the example.
Screen 2:
class DetailsClassWhichYouWantToPop {
final String date;
final String amount;
DetailsClassWhichYouWantToPop(this.date, this.amount);
}
void getDataAndPop() {
DetailsClassWhichYouWantToPop detailsClass = new DetailsClassWhichYouWantToPop(dateController.text, amountController.text);
Navigator.pop(context, detailsClass); //pop happens here
}
new RaisedButton(
child: new Text("Edit"),
color: UIData.col_button_orange,
textColor: Colors.white,
onPressed: getDataAndPop, //calling pop here
),
Screen 1:
class Screen1 extends StatefulWidget {
//var objectFromEditBill;
DetailsClassWhichYouWantToPop detailsClass;
MyBills({Key key, this.detailsClass}) : super(key: key);
#override
Screen1State createState() => new Screen1State();
}
class Screen1State extends State<Screen1> with TickerProviderStateMixin {
void getDataFromEdit(DetailsClassWhichYouWantToPop detailClass) {
print("natureOfExpense Value:::::: " + detailClass.date);
print("receiptNumber value::::::: " + detailClass.amount);
}
void getDataFromEdit(DetailsClassWhichYouWantToPop detailClass) {
print("natureOfExpense Value:::::: " + detailClass.natureOfExpense);
print("receiptNumber value::::::: " + detailClass.receiptNumber);
}
void pushFilePath(File file) async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Screen2(fileObj: file),
),
).then((val){
getDataFromScreen2(val); //you get details from screen2 here
});
}
}
The simplest way to achieve this is to :
In your body take a WillPopScope as the parent widget
And on its onWillPop : () {} call
Navigator.pop(context, false);
onWillPop of WillPopScope will be triggered automatically when you’ll press the back button on your AppBar
While you can override the back button for custom behaviors, don't.
Instead of overriding the button with a custom pop, you should handle the null scenario.
There are a few reasons why you don't want to manually override the icon:
The icon change on IOS and Android. On IOS it uses arrow_back_ios while android uses arrow_back
The icon may automatically disappear if there's no route to go back
Physical back button will still return null.
Instead should do the following:
var result = await Navigator.pushNamed<bool>(context, "/");
if (result == null) {
result = false;
}
Try this:
void _onBackPressed() {
// Called when the user either presses the back arrow in the AppBar or
// the dedicated back button.
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
_onBackPressed();
return Future.value(false);
},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: _onBackPressed,
),
),
),
);
}
Use the below code to get result from your activity.
Future _startActivity() async {
Map results = await Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context){
return new StartActivityForResult();
}));
if (results != null && results.containsKey('item')) {
setState(() {
stringFromActivity = results['item'];
print(stringFromActivity);
});
}
}
Complete Source Code
import 'package:flutter/material.dart';
import 'activity_for_result.dart';
import 'dart:async';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Start Activity For Result'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String stringFromActivity = 'Start Activity To Change Me \n😀😀😀';
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
stringFromActivity, style: new TextStyle(fontSize: 20.0), textAlign: TextAlign.center,
),
new Container(height: 20.0,),
new RaisedButton(child: new Text('Start Activity'),
onPressed: () => _startActivity(),)
],
),
),
);
}
Future _startActivity() async {
Map results = await Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context){
return new StartActivityForResult();
}));
if (results != null && results.containsKey('item')) {
setState(() {
stringFromActivity = results['item'];
print(stringFromActivity);
});
}
}
}
import 'package:flutter/material.dart';
class StartActivityForResult extends StatelessWidget{
List<String>list = ['😀😀😀','😆😆😆','😍😍😍','😋😋😋','😡😡😡','👿👿👿','🎃','🤖','👾',];
#override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text('Selecte Smily'),
),
body: new ListView.builder(itemBuilder: (context, i){
return new ListTile(title: new Text(list[i]),
onTap: (){
Navigator.of(context).pop({'item': list[i]});
},
);
}, itemCount: list.length,),
);
}
}
get complete running example of how to work this from
here
First, Remove the automatically appended back button (see this answer)
Then, create your own back button. like this:
IconButton(
onPressed: () => Navigator.pop(context, false),
icon: Icon(Icons.arrow_back),
)
You can pass data/arguments from one screen to other,
consider this example:
screen1.dart:
import 'package:flutter/material.dart';
import 'screen2.dart';
class Screen1 extends StatelessWidget {
Screen1(this.indx);
final int indx;
#override
Widget build(BuildContext context) {
return new S1(indx: indx,);
}
}
class S1 extends StatefulWidget {
S1({Key key, this.indx}) : super(key: key);
final int indx;
#override
S1State createState() => new S1State(indx);
}
class S1State extends State<VD> {
int indx = 5;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(icon: const Icon(Icons.iconName), onPressed: () {
Navigator.pushReplacement(context, new MaterialPageRoute(
builder: (BuildContext context) => new Screen2(indx),
));
}),
),
);
}
}
Screen 2:
import 'package:flutter/material.dart';
import 'screen2.dart';
class Screen2 extends StatelessWidget {
Screen2(this.indx);
final int indx;
#override
Widget build(BuildContext context) {
return new S2(indx: indx,);
}
}
class S2 extends StatefulWidget {
S2({Key key, this.indx}) : super(key: key);
final int indx;
#override
S2State createState() => new S2State(indx);
}
class S2State extends State<VD> {
int indx = 1;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(icon: const Icon(Icons.Icons.arrow_back), onPressed: () {
Navigator.pushReplacement(context, new MaterialPageRoute(
builder: (BuildContext context) => new Screen1(indx),
));
}),
),
);
}
}
To pass data between Screens, pass the argument/data to the Screens constructor in Navigator.pushReplacement().You can pass as many argument as you want.
This line
Navigator.pushReplacement(context, new MaterialPageRoute(
builder: (BuildContext context) => new Screen1(indx),
));
will go to Screen1 and call initState and build method of Screen1 so that you can get updated values.