Pressing back button calls onCreate (Android) - android

Activity A starts Activity B. In Activity B, I have this method:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpTo(this, new Intent(this,
ArticleListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
When I press that home button, it takes me to Activity A as it should. However, onCreate is being called again. I do not want this behavior.
I'm guessing its because this implementation uses new Intent to previous item in the navigation stack. This is just code I got from Eclipse when creating the double pane project though. I looked around on stack overflow, and though it seems that using an Intent to go back is causing this behavior, I do not understand why Google would provide this in a default template.
How should I make this call differently so that onCreate is not called again when going back to Activity A?

#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
just finish current activity it will take you on previous activity
if your previous activity is activity A then just use finish(); method instead of creating object of intent

As pointed out by #Rajesh you need to call onBackPressed().
Your code detects the home button press and creates a new ArticleListActivity class.However, you don't want to create a new class you only want to go back to your already created class/activity. so use onBackPressed() instead.

You can try to set the launch mode in the manifest, because the parent activity can be popped off the stack.
android:launchMode="singleTop"

In this way, the onCreate() is not called again.
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}

Related

Have Up button act the same as android back button

My android application has the following activity flow
Listing -> Buy -> Sell
From the listing when an item is clicked/selected an id is passed to buy to pull the relevant data from the server. If a user owns a certain item there will be a sell option as well from the buy screen (which doubles as an overview of said item).
The problem I am facing is that when you are on the sell screen and press the android back button you are taken back to the buy screen in it's original state, however when you click the back arrow (up) from the activity in the toolbar, it seems that it is actually trying to launch a new activity and throws an exception (since the activity cannot know what the id was). The buy activity is listed as a parent to the sell activity in the manifest.
I need to somehow make the up button to act the same as the back button on this particular activity, or at least pass the id back somehow.
Any suggestions would be appreciated.
If you're using an ActionBar (either platform or AppCompat) override the following method in the activity from which you wish to go back.
#Override
public boolean onOptionsItemSelected(#NonNull final MenuItem item) {
final int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
This should be safe to use in a simple navigation hierarchy such as yours.
Just yesterday i did this for my app. This is what I did:
In manifest file I removed
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app.MainActivity" />
that was part of my DetailsActivity.
In the DetailsActivity I added this line to onCreate
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
and in onOptionsItemSelected() method I added these lines
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
Not sure if it is the best way to handle this but oh well it works :)
In your Activity, onOptionsItemSelected() method get the clicked item id, if the id is android.R.id.home then just finish() current activity.
Try this:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}

Issue while moving from current activity to previous activity using getSupportActionBar().setDisplayHomeAsUpEnabled(true)

I have few activities and I want to move current activity to previous, like A->B->C-D, here i want to go to D->c->B->A, I have added respective parent activity name in manifest for all activities but when i press arrow in activity D its goes to activity A directly, if i backpress then it is coming to C activity,
How to to it properly?
You may override your onOptionsItemSelected-method to achieve the same behaviour in both cases...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
onBackPressed();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
This is a regular proceed of your back button. You can read more about it at the official website.
You can set flags to your intent, if you want to get other behavior.
Link

How to finish activity with custom animation when home button pressed

I have an ActionBarActivity "B" whose parent is ActionBarActivity "A" (also defined in manifest). A is in "singleTask" launch mode. I have an animation when starting B from A as follows:
public void onItemClick(...) {
Intent mIntent = new Intent(getActivity(), B.class);
startActivity(mIntent);
getActivity().overridePendingTransition(R.anim.B_in, R.anim.A_out);
}
On B, I have the following onOptionsItemSelected and onBackPressed:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
getSupportFragmentManager().popBackStackImmediate();
//onBackPressed();
//finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(R.anim.A_in, R.anim.B_out);
}
Here is the problem: When I press back button, the animation at onBackPressed is taking place as expected. However, when I click on icon at top left in the actionbar, popBackStackImmediate is called and Android's default animation is played which is different. So:
How can I manage to get same animation as in onBackPressed?
Should I use onBackPressed() instead of popBackStackImmediate()? Will it give the same result as popBackStackImmediate do?
Any suggestions and best practices are welcome...
You could use .popBackStack() instead of popBackStackImmediate() then overrride the pendingTransition, that might work. Since these are both activities though, my inclination would be to call finish(); then overridePendingTransition().

Implementing ActionBar Up button

I am implementing the Up button in the ActionBar using this method posted here:
ActionBar Up button and Navigation pattern
It works ok except in one scenario: If Activity A creates Activity B, and then I press Up it will navigate to A no problem.
However, when I get to Activity B, and then I switch to another App, then switch back to my App, and now I press the Up button, it will navigate me to the home screen instead of Activity A.
When I debug I can see that NavUtils.shouldUpRecreateTask(this, upIntent) returns false in both cases, and the upIntent is indeed Activity A for both cases as well. So not sure what the problem is.
#SuppressLint("NewApi")
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is NOT part of this app's task, so create a new task
// when navigating up, with a synthesized back stack.
TaskStackBuilder.create(this)
// Add all of this activity's parents to the back stack
.addNextIntentWithParentStack(upIntent)
// Navigate up to the closest parent
.startActivities();
} else {
// This activity is part of this app's task, so simply
// navigate up to the logical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
//finish();
return true;
} else if (itemId == R.id.wrap_menu_item) {
wrapText();
invalidateOptionsMenu();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
Changed Activity A property from
android:launchMode="singleInstance"
to
android:launchMode="singleTask"
resolved the issue. Makes sense because A "singleInstance" activity, permits no other activities to be part of its task. It's the only activity in the task. If it starts another activity, that activity is assigned to a different task. So the only reason Up was working before was because Activity A was "underneath" the previous activity: it gave the illusion it was going back to previous activity.

Android Actionbar Up button versus system Back button

I'm using the Actionbar and it's "up" button to return from a detail activity to the main activity, which works fine. Similarly, the user can press the system "back" button to return to the main activity.
In my main activity, in onCreate() data is downloaded from the internet to display upon app start. I noticed that when I use the Actionbar "up" button to go from detail to main activity, onCreate() is run, re-downloading the data. But onCreate() is not run when I use the system "back" button, therefore immediately showing the main activity view.
The code I use in the detail activity to implement the "up" button is:
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
I would like the "up" button to behave like the "back" button and not rerun onCreate(). But I'm unsure how to make this happen, or which code path the "back" button implements to return to the main activity.
Thanks!
Instead of starting a whole new activity simply finish the details activity you are in
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
Then you will return to the previous activity on the activity stack (your main activity) and onCreate shouldn't be called
If you want Up to do exactly what Back does, you can do this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
Note that the default implementation of onBackPressed() just calls finish(), but onBackPressed can be overridden.
I think a better solution can be found in this post.
Calling finish() works in specific situations but may not always produce the behavior described in the documentation e.g:
By calling
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
NavUtils.navigateUpTo(this, intent);
you'll return to the parent activity in the state in which you left it. If you have a flat app structure, it'll still act just like the Back button.
for a real "home" functionality , you should see the api demos ,under "App/Activity/Reorder Activities" .
the reason : what if you have something like this : activity1->activity2->activity3 , and now you wish to go to activity1 by pressing the home button on the action bar?
I believe the simplest way is to override the "getParentActivityIntent" method of the detail activity adding the flag "Intent.FLAG_ACTIVITY_CLEAR_TOP":
#Nullable
#Override
public Intent getParentActivityIntent() {
Intent intent = super.getParentActivityIntent();
if (intent != null) {
return super.getParentActivityIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
return intent;
}
There is another solution which can be in hand for somebody. I had the same double-behavior when user pressed Back and ActionbarBack buttons. I was fine with Back btn behaviour. I didn't want an activity to be recreated. So I overrode the method
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
Works fine for me

Categories

Resources