So I would like to know how I can manage the back stack for activities that are launched from the NavigationDrawer. If I launch various activities via the NavigationDrawer by default Android will add them to the back stack and it would cause back button hell as user.
I imagine this should be a common problem so there must be a adequate solution.
But I need a solution to cater for the following 3 requirements.
Requirement 1)
I have 2 items in the navigation drawer (Activity1 and Activity2) which each launch different Activites. If I open the items via the navigation drawer a number of times when I press back I wish to go back to the initial starting activity and if I press back again I wish to exit the app
Requirement 2)
I launch Activity 1 from Nav then I launch Activity 2 and from within this activity I launch a new activity SubActivity. Now when I press back I would expect to be taken back to Activity 2 and then if I press back again I would expect to be taken to the initial Activity (not Activity 1), and then pressing back again would exit.
Requirement 3)
Same as above but actually the initial Activity is dynamic. So the landing Activity is defined by a user setting about what their first screen shall be.
As you can see I can not use NO_HISTORY flag because of (requirement 2)and I cant hardcode the parent of the Activities because of (requirement 3).
So other than overriding the back button is there any other way that i can manipulate the back stack ?
Thanks
Launch mode will not help. The answers lies in using TaskStackBuilder, its a very powerful api that allows you to define exactly what is to go into the backstack of the activity that you are about to launch. Here is how to use it.
Intent activityInBackstack = new Intent(this, ActivityA.class);
Intent activityToBeLaunched = new Intent(this, ActivityB.class);
TaskStackBuilder builder = TaskStackBuilder.create(this);
builder.addNextIntent(activityInBackstack);
builder.addNextIntent(activityToBeLaunched);
builder.startActivities();
So now if you are in ActivityB and you press back button you will always go to ActivityA. Pressing back on ActivityA would exit the app.
Related
In a interview someone asked me this question. Suppose there are 4 activities in application. He wants back button to work normally on first three activities(i.e. going to previous screen on back button press); except the last.
He wanted that, when he press back button on fourth activity(screen), user should go to Home Activity(Starting Screen or first screen). But the contents on Home Activity should be same when user went from first screen to second screen. So I think, I can't use Intent, as it will create new instance of Starting Activity.
He wanted that, when he press back button on last activity(screen), user should go to Home Activity(Starting Screen or first screen).
The interviewer should be interviewing for his or her own replacement, if (s)he thinks that hacking the BACK button this way is a good idea.
So I think, I can't use Intent, as it will create new instance of Starting Activity.
Add FLAG_ACTIVITY_REORDER_TO_FRONT or the combination of FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP to the Intent used with startActivity() to bring up your "home activity". Either will cause the existing "home activity" instance to come to the foreground. If you want all other activities to be destroyed, use the second approach (FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP).
Here is my situation:
I have MAIN activity, four TOOLBAR activities, that user can launch from always visible toolbar and other activites.
What I want:
App start with MAIN Activity. Then user goes to Main -> TOOLBARActivity (1) - OtherActivity(1) - OtherActivity(2) - ... - TOOLBARActivity(2).
When launching the TOOLBARActivity(2) I need to clear all stack from Main till TOOLBARActivity(2). So if now user will press the back button, he will return to MAIN Activity.
So, I simply need find the way to clear all activities in stack except the first one.
When you go to your second Activity you can use like this :
intent = new Intent(this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
StartActivity(intent);
this flag clears top of Activity stack
I do totally agree with the Navigation below
Imagine that the Book detail is made in different instances of a BookDetailActivity.
The stack before pressing up in book2 detail is:
BookDetailActivity (Book 2 - You are here)
BookDetailActivity (Book 1)
AllBooksActivity
If I follow the guidelines I will use:
Intent parentActivityIntent = new Intent(this, AllBooksActivity.class);
parentActivityIntent.addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();
But the big problem with this code is that BookDetailActivity (Book 1) is still alive!
Pressing back button after "up" would bring the detail of Book 1.
How can I kill all the BookDetailActivity that are between the original AllBooksActivity and the activity where I pressed up?
The related guidelines article notes the following:
Implementation Note: As a best practice, when implementing either Home
or Up, make sure to clear the back stack of any descendent screens.
For Home, the only remaining screen on the back stack should be the
home screen. For Up navigation, the current screen should be removed
from the back stack, unless Back navigates across screen hierarchies.
You can use the FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK
intent flags together to achieve this.
Since you're doing that, BookDetailActivity1 should be closed by FLAG_ACTIVITY_CLEAR_TOP. The only way if it could be alive and shown on pressing Back is if it would have been started before AllBooksActivity.
As for not needing FLAG_ACTIVITY_NEW_TASK (suggested by android developer's answer):
When using this flag, if a task is already running for the activity
you are now starting, then a new activity will not be started;
instead, the current task will simply be brought to the front of the
screen with the state it was last in.
...so if your activity exists, it will not start a new task.
ok , there are multiple ways to do such a thing. here's one of them:
however , i would suggest that instead of opening the first activity as if it's a new one , simply finish the current one and the one before it .
in order to do it , call each new activity with startActivityForResult , and set the result for each of the activities to some value that says you wish to return to the first activity .
you can even set the value to be the class canonical name , and make a base activity that will handle all of those requests automatically so that you won't need to handle it .
in any case , i think you made a mistake by using Intent.FLAG_ACTIVITY_NEW_TASK since it creates a new task , so the previous one still exists . try to read the available intents flags for more information:
http://developer.android.com/reference/android/content/Intent.html
I have application with main activity and some more.
On each other activity there is the logo of the application.
When user presses the logo button, I want to get back to the main activity.
I do not want to create new intent, since activity aready on the activity stack.
How can I get it - use the one on the stack?
How can I clear the whole activity stack, so back button will actually exit from the application instead of getting back to the previous activity?
Yoav
I do not want to create new intent, since activity aready on the activity stack.
If you start an activity (via intents or any other way) which was already started and is on the stack , then Android just takes that same instance of the activity and places it on top of the stack. A new instance is not created. Ofcourse this happens if you did not manually kill the activity (by calling finish() in it).
How can I clear the whole activity stack, so back button will actually exit from the application instead of getting back to the previous activity?
Its not recommended to override the back button to quit the application in every activity(Unless your app has strong reasons to do so). generally the app should let the user go back to the previous activity when he presses the back button (which is what a user might be expecting).
If you still would like to quit with the back button then you can override the back button function and launch the intent that leads to the home screen:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I faced a somewhat similar problem. The following link might be helpful for you:
clearing stack of activities with just one press
Its very simple.
Don't call finish() on Home/Main activity.
For Ex: Say you have 4 activities.. If your requirement is like this .. Act1-->Act2-->Act3-->Act4-->Act1 . So, don't call finish() on Act1. But call finish() on Act2, Act3 while you are going to other activity. So when you click on logo in Act4, just call finish(). So, automatically you will come back to Act1 which is your Main activity.
If you have logo in Act2, Act3 also then call finish() on click of logo to go back to Main. But remember to call finish() on Act2 while you are going from Act2 to Act3
I am new in android and I have total 6-7 activities in my application. I want to know how can I manage my activities properly means when I move to the A->B->C->D like that. Then how can I move that the stack of these activities not created.
On moving from one activity to the other I am using the below code:
Intent intent=new Intent(current.this,next.class);
startActivityForResult(intent, 0);
And now if I want to move back on the earlier activity I used the code as:
Intent start = new Intent(current.this,next.class);
startActivity(start);
finishActivity(0);
Is there a special reason that you don't want to use the activity stack and let the activities handle themselves?
The Android system has done a very good job with the activity lifecycle. It allows you to start an Activity from different places without confusing the user because the back button will bring the user back to a different activity.
If you don't have a very good reason to not use the Android guideline try to stick to the way the system is doing it. Every other thing will only give you problems.
You are starting activities for a result but how I understand you you will never return to them.
You can start an Activity and after that just finish the current Activity. That way the activity will not be put on the back stack. Now you need to listen for back button pushes and create the activities that you want to bring the user to.
If you want to move from Activity A to D like going to the start/home screen of you app you do the following:
Intent goBackToA = new Intent(context, StdActivity.class);
goBackToA.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(goBackToA);
The flag FLAG_ACTIVITY_CLEAR_TOP will tell the system that if the backstack contains an instance of the Activity this activity will be shown and all activity that are between the current activity and the target activity are removed from the backstack. This allows you to go back to a home activity without creating huge loops that the user can move through with the back button.
To move back to the previous activity you don't have to create a new intent, you can simply call this.finish() on the one that should dissapear.
To move back to the previous activity you don't have to create a new intent, you can simply call this.finish() on the one that should dissapeear or you can press Back button to see the previous Activity .
whenever you want to navigate from one class to another use this code, may be this help you to navigate the Activity,
Intent nextpage = new Intent(CurrentActivity.this,NextActivity.class);
startActivity(nextpage);
this.finish();