I want to implement Navigation Pattern in my app with Up button in ActionBar.
I have Details Activity, here I can come from home, favorites and search screen. Also I can open this screen from browser(handling specific url). When user press Up button, I use flush() method, to emulate back navigation. But for case, when user come from browser, I want to open home screen instead of previous browser activity. How I can recognize, that previous activity was from another app, and navigate to home screen?
Up Should always navigate to the hierarchical parent of the activity and Back should always navigate temporally.
In other words you should leave Back as it is.
As for Up, it should always go to the same place no matter where it came from. So if you normally come to the DetailsActivity from YourListActivity, Up should always go there no matter where you came from. What is the most likely place is up to your discretion, but it should always be the same.
If you come to the Details Activity from a non-normal location (such as the browser, another activity, widget, or notification) you should recreate your task stack so navigation using up results in the same path. Here is an example from the Android Developer Training:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, YourListActivity.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is not part of the application's task, so
// create a new task
// with a synthesized back stack.
TaskStackBuilder
.from(this)
.addNextIntent(new Intent(this, HomeActivity.class))
.addNextIntent(upIntent).startActivities();
finish();
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
}
Here is the Android Training on Implementing Navigation
(http://developer.android.com/training/implementing-navigation/index.html).
You will need the support library for NavUtils and TaskStackBuilder.
Related
Short problem description: starting new activity at menu seems to lead to multiple main activities (at least via 'Back' navigation), and I can not find a "standard" way to navigate Activities.
Details:
I am writing a really small, simple and straight forward app with one main activity and two "sub" activities, namely show and settings. Both sub activities are declared with android:parentActivityName="mainActivity". In the menu I want to let the user switch between those activities.
I have read the android developer tutorial to create a menu, this tutorial stops at newGame() and showHelp() in onOptionsItemSelected. Other tutorials led to the following:
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "onOptionsItemSelected! " + item.getItemId());
Intent intent;
// Handle item selection
switch (item.getItemId()) {
case R.id.settingItem:
intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
...
Of course the main activity should be also included in this menu, but I also want the "Up" and "Back" to be working as usual.
So my question is which style is androidish? The main activity is quite expensive in creating, since it uses Camera and Camerapreview.
Destroy the mainActivity with finish() everytime a 'settings' or 'show' is called, and create it again on 'Back', 'Up' and 'main activity' events?
Write three different menus or onOptionsItemSelected for the main activity (which does nothing when 'main activity' is chosen) and each sub activity?
Save the Intent for the main activity and try to reuse this?
If there already is some tutorial out there (for a API level >= 11) defining the simple switching between the apps, I really would like to read it. But I'm quite lost in all I have found now.
I've read the Android Docs on the lifecycle of an activity. However, I am curious as to how different activities within an application behaves.
From some tests that I've done, transitioning from Activity A to Activity B within the same application via an intent pauses Activity A via onPause() and creates Activity B via onCreate().
The strange part is when Activity B transitions back to Activity A.
If the hardware back key is pressed, onPause() is fired for Activity B and onResume() is fired for Activity A. This is what I would expect.
However, if the back button on the ActionBar is pressed, onDestroy() is fired for Activity A followed by onCreate() and onResume().
Why is this so?
The "back button" on the ActionBar is called the "Up Button". This is the expected behaviour of the Up Button, if you take a look of the implementation of the code which performs the "up", you see that Activity A is recreated.
Intent parentActivityIntent = new Intent(getApplicationContext(), MainActivity.class);
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();
You can define what the "Up" button should do, however, I suggest to stick to the default behaviour.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// Your Code Here.
break;
}
}
Why?
The Up Button (in contrast to the back button) should navigate one level higher in the application hierarchy, always. The back button should go back, even if it will leave the current application.
You can't just call finish on the current Activity, because the parent Activity could already be garbage collected and don't exist anymore.
I heavily suggest to read the official Android Design Guidelines, especially the part about Up vs Back.
On my apps home page I have an option to add items to a ListView using adapter.add(string). I also have another Activity that my app goes to using startActivity(intent). When I am in that second Activity and I press the back button all of the data that was added to the list is still there, however when I press the icon at the top left all the data is gone. Is there a way to make it so that the button for the icon preserves the data in my list. I think I should note that I don't want the data to be preserved when the app is closed, only when navigating through the open app.
This is my current method that handles the home button action:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
A quick solution would be to call onBackPressed() instead of NavUtils.navigateUpFromSameTask(this). This, however, isn't recommended and you should try to implement proper navigation logic. Take a look at the answers to this question as well as these tips.
I have Activity A (Main) and Activity B.
Fact: Activity A has: android:launchMode="singleInstance"
Usual scenario is:
User launches application > Activity A.
User clicks an item > Activity B
3.A. If user clicks on back/up buttons > Back to A (without calling finish() on B)
User clicks the SAME item as before > Forth to B.
At this point he can go back and forth without new instances. It's all in the stack and it doesn't recreate activities. (All right!)
3.B. If user clicks Home, then goes to task manager and brings the app to front > Activity B (all good, so far)
If user clicks UP button, it goes to TASK MANAGER, and I want it to go to Activity A (back button is expected to work this way, so let's focus on UP button).
Here's the implementation I have in Activity B for BACK and UP buttons.
#Override
public void onBackPressed() {
moveTaskToBack(true);
// I don't want to finish() the activity, so the user can reclick the same
// item without reloading the whole activity again (webview slow when parsing html).
return;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
moveTaskToBack(true);
// I don't want to finish() the activity... idem.
// I need to implement here the bring Activity A to front
break;
}
}
So, what I want is: to "Go Back" to Activity A keeping the same idea of using the stack to reload Activity B if needed, without using Intents (unless it calls activity to front, without adding items to the stack.)
Let me know if I explained myself clearly and if you need more info.
UPDATE:
I've found this at: http://developer.android.com/training/implementing-navigation/ancestral.html
This is how I adapted it.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, Activity_A.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
} else {
moveTaskToBack(true); // I want it this way. Don't worry.
}
break;
}
}
But the method NavUtils.shouldUpRecreateTask is ALWAYS returning false.
I did the http://developer.android.com/training/implementing-navigation/ancestral.html#SpecifyParent part, so that's not the issue.
My problem is that I want to recognize if Activity A exists in the stack, for when i.e. the app is launched from the task manager.
How can I achieve this?
Thanks.
moveTaskToBack moves the entire task to the background. it doesn't finish the activity.
in order to have full control of activities, you have some possible solutions:
create your own global manager for the activities, monitor each of them through all of their lifecycle and decide what to do on each event.
you could also finish each activity as soon as you go from it, and put "it" (just its name or something) in a stack and restore its state when you come back to it.
use fragments instead, and manage them all on a single activity. be warned of configurations changes though.
I am developing an android app. I want my app to have a home button. So I decide to use a clickable ImageView for that, which I am placing in the title bar. Whenever a user clicks on the home image, the app will navigate to the home screen: which I accomplish by having the image dispatch an intent to start the HomeActivity.
My concern is that the whole approach feels like poor design (I may be wrong). Basically all activities follow the HomeActivity. And since I don't normally call finish() on my activities (so to allow back-button navigation) would I end up in a loop? As in, say a user goes from HomeActivity to FooActivity then to BarActivity then clicks on the home image hence going to HomeActivity. I know I can rely on android to reclaim memory when it needs it. But I don't want my app to tax the system so much.
So how do android designers normally design home icons/buttons so to avoid this looping problem? Or is android aware that I am returning to HomeActivity and thus may finish the previous instances of the other activities I just walked through?
Using the App Icon for Navigation for this
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}