Reputation: 2690
I've got 4 screen. X,A,B,C. The navigation pattern should be as follow
Here is code
X Screen
class X extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: FlatButton(
child: Text('Navigate to A'),
onPressed: () {
A.show(context);
},
),
);
}
}
A screen
class A extends StatelessWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => A(), fullscreenDialog: false),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FlatButton(
child: Text('Navigate to B'),
onPressed: () {
B.show(context);
},
),
),
);
}
}
B class
class B extends StatelessWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => B(), fullscreenDialog: false),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FlatButton(
child: Text('Navigate to C'),
onPressed: () {
C.show(context);
},
),
),
);
}
}
C class
class C extends StatelessWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => C(), fullscreenDialog: false),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FlatButton(
child: Text('Navigate back to A'),
onPressed: () {
A.show(context); //<=== here is problem
},
),
),
);
}
}
Problem I've got is when I navigate from screen C back to screen A and press back button on app bar then it get me back to screen C. I need to be able to navigate back from C to B, B to A, and A to X but once I navigate from C to A I need to navigate back to X or again to B on pressing the button
UPDATE
I guess I kinda managed that with try and fail technique and honestly I don't understand why does it work as I want. Please if you know why this works and have an explanation then please provide an answer. Here is what I did
I've added new static function in Screen A
static Future<void> back(BuildContext context) async {
await Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => A(),
fullscreenDialog: false),
ModalRoute.withName('/'));
}
and call it in my screen C in my button
A.back(context)
Upvotes: 3
Views: 9052
Reputation: 909
class C extends StatelessWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => C(), fullscreenDialog: false),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FlatButton(
child: Text('Navigate back to A'),
onPressed: () {
int count = 0;
Navigator.of(context).popUntil((_) => count++ >= 2);
},
),
),
);
}
}
Upvotes: 1
Reputation: 1781
Change your code
class A extends StatelessWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => A(),
settings: RouteSettings(name: 'A'), // <-- change 1 give a name
fullscreenDialog: false),
);
}
...
class C extends StatelessWidget {
...
onPressed: () {
Navigator.popUntil(context, (route) => route.settings.name == 'A'); //<=== will pop until A change 2
...
Whats going on in your Update A.back
?
Drawback - on iOS swipe back
behavior invoking Navigator.pop
and there is no straight way to call your A.back
in this case
static Future<void> back(BuildContext context) async {
await Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => A(),
fullscreenDialog: false),
ModalRoute.withName('/'));
}
Upvotes: 1