Flutter go_router, how to get the whole current stack of pages? - flutter

Meaning if I go from a job screen to a client screen (the client the job was for), to another job screen (another job done for the client) etc, how can I display job > client > job?
And including parameters, so I could display Job 12 > SomeCompany > Job 17.
Sub routes aren't sufficient because the stack can repeat through multiple of the same pages infinitely.

I'm not sure about checking the whole stack , but in case of anybody needed to check if there is a page on the stack , GoRouter has a canPop() method:
/// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop();

This isn't possible with go_router. auto_route has an API to check the stack, but go_router shows no search results for stack.
Instead of GoRouter.of like in this answer, you could use the extension method BuildContext#canPop. For example, in my onboarding page, I have this logic to pop if I can, and if not possible (the first time someone launches the app), I replace the page.:
if (context.canPop()) {
context.pop();
} else {
context.replace(Routes.dashboard);
// Or alternatively, allow the user to navigate back to onboarding with:
// context.push(Routes.dashboard);
}

Related

How to see GoRouter navigation stack's top element without poping it?

I am building a flutter app. I have a place in the app where you can make infinite loops with
GoRouter.of(context).push(...);
I mean you can navigate to Screen A and then to B and then to A. There are many screens and many possible loops but I want to protect the user from the most obvious one, the A>B>A>B type.
(I don't care about greater loops like A>B>C>A>B>C and alikes)
To do that, I want to check the navigation stack top element and if the element is the same where we would go with a push, I would do a pop.
Problem is that I can't find anything on Google...
Tried:
Googling it, checking API docs, reading IntelliSense
EDIT:
There is a big set of screens and can't know the previous location solely based on the current one.
Use GoRouter.of(context).location
GoRouter.of(context).location gives you the current location
Example:
Route A has route path /routeA
Route B has route path /routeB
GoRouter.of(context).location will return either /routeA or /routeB
Based on which you can make decision to pop() or push() page

Flutter: push multiple pages on stack

I am using Getx for route management.
When coming from deepLink and the app is terminated, I want the app to launch (with splashscreen) and then go to a specific /match/:match_id route (I have the id in the deepLink).
This works well. The problem is that I want to push below this match page, the home page so that when the user goes back he can go there.
Within the initState of the LaunchScreen widget I am doing
Get.offNamed("/home"); // remove `LaunchScreen` and push `Home`
Get.offNamed("/match/:" + match_id); // push `Match`
This works. However there is some inconsistency with animations. I see for few seconds the Home page and then immediately the Match
I would like to jump directly to Match and the user not even seeing the Home one

Flutter how to navigate back to a particular page

I have an app with multiple pages where some pages are skip depending on the user selection...
for example, I have the following page
details.dart
contact.dart
address.dart
code.dart
summary.dart
I would like to go to another page from any of the above pages...However, I want first check to see if they are in the stack and then pop to it. Otherwise push that page onto the stack
How do I do this in Flutter
I think you might want to use Navigator.of(context).pushNamedAndRemoveUntil or Navigator.popUntil.
They are very similar however like the name suggests pushNamedAndRemoveUntil pushes a new route when the predicate matches, while popUntil re-uses an existing Route/Widget in the tree.
You can read more about them on this wonderful Medium post explaining all options in greater detail.
You can use routes inside materialApp, after home
return MaterialApp(
home:... ,
routes:{
"/routeName" : (context) => PageRoute()
}
and then call route name from any pages
Ex : app in Contact page need to move to PageRoute
//Contact Page
...
onTap:(){
Navigator.pushReplacementName(context,'/routeName');
}
just use multiple Navigator.pop

what is the difference between ActivityStack and TaskRecord

I'm studying with AOSP, and I found ActivityStack and TaskRecord in "ActivityStack" Class. There is explanation In https://developer.android.com/guide/components/tasks-and-back-stack , Back-stack(=Activity Stack) And Task seems similar to me... What is the the difference between ActivityStack and TaskRecord?
In this https://developer.android.com/guide/components/tasks-and-back-stack,
Focus on below lines, For Task
A task is a cohesive unit that can move to the "background" when users begin a new task or go to the Home screen, via the Home button. While in the background, all the activities in the task are stopped.
For back stack
The back stack for the task remains intact—the task has simply lost focus while another task takes place. A task can then return to the "foreground" so users can pick up where they left off.
For info you can refer below links:-
What is the relationship between Task and Back stack
https://blog.mindorks.com/android-task-and-back-stack-review-5017f2c18196
https://medium.com/google-developers/tasks-and-the-back-stack-dbb7c3b0f6d4
If you think of activity back stack as two levels, it might be easier to understand the purpose of ActivityStack. Android supports launchMode and taskAffinity to put activities into different TaskRecords. But even activities are put into different TaskRecords, it keeps supporting the back button to switch back to previous activity. So when you launch activity that needs to be in new TaskRecord, then back button is pressed, it switches to top activity of previous TaskRecord. So ActivityStack is more like a TaskRecord stack, and TaskRecord is more like the activity stack inside the TaskRecord, however, general speaking, ActivityStack controls the pop up sequence, and you can say it's an indirect activity stack.
And creating ActivityStack seems to make management easier logically in multiple window environment. If you enable free form in Android, each launched window mode app has its own free form stack, and each stack has its own back stack.
My 2c.

Lifecycle and Activity Stack

In the application activities are stacked like this: A - > B - > C - > D - > E.
If I receive a particular notification and click on it, Activity E is started.
If I then click back (button on phone or button on actionbar), the application exit.
How do I make the transition to Activity D in this case, and then back through C, B, and A?
My code of back button:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return true;
}
Everything is okay when starting the application normally. The problem is when Activity starts from the notification.
Android has the functionality you're after built in, and it is already well documented. To begin with you should look at the TaskStackBuilder class. It was introduced in JellyBean, but is already included in the support library, and you use it to build a synthetic TaskStack which is what you need. A summary from the documentation reads:
When crossing from one task stack to another post-Android 3.0, the application should synthesize a back stack/history for the new task so that the user may navigate out of the new task and back to the Launcher by repeated presses of the back key. Back key presses should not navigate across task stacks.
TaskStackBuilder provides a way to obey the correct conventions around cross-task navigation.
How you build it is going to depend on the relationships of the Activities in your app, but the Tasks and Back Stack developers guide is a good read to help you decide, as is the Navigating with Up and Back design guide, if this is all new to you.
You'll find some code examples in the Implementing Effective Navigation lessons, also on the Android developers site, in the training section.
Incidentally, the button on the ActionBar is referred to as Up. Even though it sometimes shares the same functionality as the back button, the two are not the same (I assume that's the one you are talking about ;-) .)
I think you can solve your problem by sending an intent from Activity E to Activity D, and so on.
Therefore you should overwrite the method
onBackPressed()
that is called when you click on the back button.