I've had a look at this question-
Call OnResume when Back Button Pressed when using Fragments
I've done the same things, as mentioned in the answers, but neither is onResume called, nor onCreateView. It's a transaction from an activity to a fragment, all of which are a part of a single tab. How can I call a method from the first fragment when back button is pressed on the second fragment?
Code-
Bundle data = new Bundle();
data.putString("q", code);
data.putString("type", type);
data.putString("name", name);
viewPager.setCurrentItem(1);
android.support.v4.app.FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
eq equity = new eq();
equity.setArguments(data);
transaction.replace(R.id.root_frame, equity).addToBackStack(null).commit();
The method called when you press the back button is onOptionsItemSelected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
if (yourCondition = true) {
//do something here
} else {
super.onBackPressed();
}
}
But onOptionsItemSelected is called on the parent activity.
I don't know if the back button is required, but I think it's better to implement a callback from one fragment to the other with an Interface and using a custom button not the back button.
fragment life cycle is directly effected by the host's activity life cycle so you gotta take that in consideration anyway did you try to call the method in onPuase() or in onStart() in the fragment that you are heading for after pressing back ? if that didn't work try to reach the emulator back button from if (keyCode == KeyEvent.KEYCODE_BACK) or you can finish() the previous fragment or activity so the back button will get the user no where and create your own back button to redirect the user and replace the method in it using onClick() .
hope that will work for you good luck
Related
I've got an app with nav drawer, which is switching fragments. From inside one of those fragments, I am calling a new activity. When I click back in this activity (in toolbar), I want to go back to previous selected fragment but instead it puts me back to first fragment. I am adding my fragment to back stack so this should not be a problem.
Here is what I have already tried:
I have overriden the onBackPressed method in my 2nd activity like this:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
It is not working. I also saved index of current fragment inside onsaveinstancestate method and retrieve it but same result. I also tried with always putting current fragment inside variable and try to reshow it but still, it does not work. Anything else I could try?
Fun fact: if I press back inside bottom panel, it does actually goes back to previous fragment.
EDIT: Here is my code for doing this:
private void replaceFragment(Fragment fragment)
{
if (fragment != null)
{
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.main_content, fragment)
.addToBackStack(null)
.commit();
}
}
I add first fragment only, if savedInstanceState is null, like so:
if (savedInstanceState == null) {
// first time
mTitle = getResources().getString(R.string.home);
replaceFragment(HomeFragment.newInstance());
}
And yes, all this is done inside onCreate() method.
I had the same problem and got fixed. The only thing you need to do is to
override the method "onOptionsItemSelected" in the activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
android.R.id.home is your first fragment in the menu.
What I tend to do is this
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
super.onBackPressed(); //replaced
}
}
This way it handles the fragment stuff on its own within, but when there's no fragments left to go back to, then it finishes the activity.
EDIT: UP navigation can recreate your previous activity even if it already exists. To prevent that from happening, redefine the Up navigation's event in onOptionsItemSelected like so:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent parentIntent = NavUtils.getParentActivityIntent(this);
if(parentIntent == null) {
finish();
return true;
} else {
parentIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(parentIntent);
finish();
return true;
}
}
return super.onOptionsItemSelected(item);
}
When you call an activity from other activity's fragment, then the previous activity's instance state that is the calling activity which was having fragment's instance state will be saved in stack...so all u need to do is finish the called activity and u will have the fragment from which you called your second activity.
#Override
public void onBackPressed() {
finish();
}
Try
getFragmentManager().popBackStackImmediate();
It worked for me.
Sorry, I don't have enough reputation to leave a comment. So I have to guess. I once had the same issue.
Sounds like a problem related to the activity lifecycle (http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle). Be sure to add your first fragment only once, because your activity's fragment manager is capable of the lifecycle.
Thus, the statement that adds the first fragment to your fragment manager should be surrounded by if (savedInstanceState == null) { ... }.
I see, that people are still trying to help me. This answer helped me fix my problem: Android - Navigation Up from Activity to Fragment
Override onOptionsItemSelected method in activity as follows,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
When you call new Activity from Fragment you should write :
Intent intent = new Intent(getFragment().getContext(),NewActivity.class);
getFragment().getContext().startActivity(intent);
FragmentManager fm = CurrentFragment.getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(CurrentFragment.class.getName()).commit();
fm.executePendingTransactions();
It Works for me.
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.addToBackStack("home") // should not be null
.replace(binding.fragmentContainer.getId(), new HomeFragment())
.commit();
Pass name in addToBackStack(String name) method. This function add fragment into backstack if passed name is not null. App automatically start managing backstack of fragment
Remove your override onBackPressed() method. No use of it now
I am creating an android application with three tabs using PageSlidingtabStrip as a library to create a swipe view.And it has three fragments.Each fragments has a list view.When the item of the listview is clicked it opens an activity and display the details.
The problem is how can i come back to the fragment in the main screen using back button in actionbar in the activity
And how can i go to the corresponding Fragment(Tab)
Try something like this :
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(YourCurrentClass.this , ClassThatYouWantToGo.class);
startActivity(intent)
}
Or actually like #TommyTopas said, you can just Override onBackPressed and put this.finish();.
EDIT
As I've understood you want to use a button on your AcitonBar, then you have tod o something like this :
First set the HomeButton enabled doing :
getActionBar().setDisplayHomeAsUpEnabled(true); Then Override onOptionsItemSelected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// or onBackPressed();
this.finish()
}
return true;
}
As I understand, when you return to the "Tab" Activity, you want to display the same tab in which the list item had been clicked. What you can do is, when a list item in any tab is clicked, save the tab number in onSavedInstanceState(), and when the Activity is recreated, then set the previously selected tab (if one was selected previously). You will get the savedInstanceState that you saved in onSavedInstanceState() back in the onCreate() of the same Activity.
You can provide an Up navigation by writing getActionBar().setDisplayHomeAsUpEnabled(true); and then in the onOptionsItemSelected method in the activity, if the item's id is android.R.id.home call the activity's method onBackPressed(); which will close your current activity and come back to your fragment
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();
}
As title says, do anyone know a way how to implement OnBackPressed functionality, just like in Activity, but in Fragment View?
It does not work when I use onKey, onKeyDown or onBackPressed in Fragment - app is closing. I would like to execute specific code when back button is pressed, because in one of fragments I have ListView, which is filled with data depending on user actions.
So when back is pressed I would like to modify values of variables ("categories" and "part"), to fill ListView with specific data (so modify some values because user clicked something, and refresh this ListView), giving a feeling that user is going back (from parts, to categories and to close the app).
But as I mentioned, when I use onKey, onKeyDown or onBackPressed, app is closing... For instance when I include in my Fragment class:
public void onBackPressed() {
Toast.makeText(getActivity(), "AAAA", Toast.LENGTH_LONG).show();
}
Toast does not appear. With "onKeyDown" and "onKey" - the same situation... What am I doing wrong here, any ideas?
To answer your very first sentance:
as title says, do anyone know a way how to implement OnBackPressed
functionality, just like in Activity, but in Fragment View?
To make the back-button work with fragments you have to add them to the backstack. That should trigger the function you want.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Finally, got it.
I had to, in my "ActionBarActivity" from method "onNavigationDrawerItemSelected" move declaration of "Fragment newFragment" to outside of this method, to make it available in whole class. Then I had to include "OnBackPressed" in my "ActionBarActivity" like this:
#Override
public void onBackPressed() {
if (!newFragment.onBackPressed()) {
super.onBackPressed();
}
}
And finally, in my Fragment I included also onBackPressed:
public boolean onBackPressed() {
if (part != -1) {
part = -1;
toAdd = "" + category + "_";
updateList();
return true;
}
return false;
}
And it works just like I wanted. When I push back, and when variable "part" in my Fragment is not -1, then it is executing operations defined above, returning true to "ActionBarActivity" so the app is not closing. But when, in my Fragment, variable is -1, then onBackPressed app is going back to main view, and again when user is pushing back, app is closing. That's what I wanted!
Thank You all for the help!
#Override
public void onBackPressed() {
super.onBackPressed();
Intent register = new Intent(PollCreateCommunities_Activity.this, PollActivity.class);
startActivity(register);
finish();
}
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
Intent register = new Intent(PollCreateCommunities_Activity.this, PollActivity.class);
startActivity(register);
return true;
}
return (super.onOptionsItemSelected(menuItem));
}
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