I have 3 fragments: Home, A and B. Home and A are in mobile navigation menu.
User goes from A to B and then press back button. The issue that if I use getFragmentManager().popBackStack(); onCreateView of fragment A is calling and I have duplicating of content.
But if I use getActivity().onBackPressed(); it goes to Home fragment instead of A.
How to display fragment A by clicking back button without refreshing the view?
Here is how I make transaction from A to B
CertificateItemFragment certificateItemFragment = new CertificateItemFragment(item);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.nav_host_fragment, certificateItemFragment).addToBackStack(null);
fragmentTransaction.commit();
You need to know some premise before using FragmentManager.
in Activity there is FragmentManager and we should call it with getSupportFragmentManager(), getFragmentManager() is deprecated.
in Fragment there are multiple FragmentManagers called ParentFragmentManager and ChildFragmentManager, the final FragmentManager which is deprecated too. And ParentFragmentManager will be same as Activity's FragmentManager
getActivity().onBackPressed() will pull out fragment if any stack exists in Activity's FragmentManager
fragmentManager.popBackStack() will pull out fragment if any stack exists in Activity's or Fragment's FragmentManager rely on who calls
Base on above points
(1) If You want to hold fragments in Activity, you should call getSupportFragmentManager() in Activity, and call getParentManager() in Fragment, then onBackPressed() will pull out the fragment you last add to stack.
(2) If you want to hold fragments in a Fragment and Separated from Activity, you should call getChildFragmentManager() in Fragment, then activity.onBackPressed() will pull out the fragment which in Activity's fragment stack and ignore other fragments in Fragment's fragment stack.
For question will be same as case (1), and if you dont want re-create fragment, you should use add() instead of replace()
in Fragment A
CertificateItemFragment certificateItemFragment = new CertificateItemFragment(item);
FragmentManager fragmentManager = getParentFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.nav_host_fragment, certificateItemFragment).addToBackStack(CertificateItemFragment.TAG);
fragmentTransaction.commit();
now onBackPressed() will backstack from CertificateItemFragment to Pre-Fragment
In normal case navigation item list menu open fragment which are replace to each other but when we move inside of any item as like in your case move from fragment A to B,
In this case normally we use another activity on which create fragment.
If you do't want to use activity then, you just need to add fragment.
try below code that may help you
CertificateItemFragment certificateItemFragment = new CertificateItemFragment(item);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.nav_host_fragment, certificateItemFragment).addToBackStack(CertificateItemFragment.TAG);
fragmentTransaction.commit();
Related
I have a navigation view that loads some fragments depending on which is pressed. In one of the fragments, I want to have a button, which when it is pressed, the fragment changes from the one loaded by the navigation view to a different fragment. I have tried using
ProfileEditFragment pef = new ProfileEditFragment();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(pef).replace(R.id.drawer_layout, pef, "Fragment")
.addToBackStack(null).commit();
When I do this, it loads the other fragment on top of the current fragment, rather than replace it, even though I used the replace function. How do I fix this?
Can you try this:
ProfileEditFragment pef = new ProfileEditFragment();
FragmentTransaction transaction =getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.drawer_layout, pef);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
I have 2 fragments A and B. I added fragment B from fragment A (A->B) with addToBackStack(). Now when I am in fragment B and press back everything is OK and return to the A.
But when I am in fragment C I want to display fragment B if it is existed in fragment manager by checking getFragmentManager().findFragmentByTag(""); then I replace this fragment.
The problem is the backstack not work in this situation. I mean whenever I press back the fragment A is not shown. How can I preserve that backstack too?
This is the code i am using
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStack(fragment.toString(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction tx = fragmentManager.beginTransaction();
Log.v("on calling fragment", fragment + "==" + fragment.toString());
tx.replace(R.id.fl_main, fragment).addToBackStack(fragment.toString());
This give different particular backstack
string to each fragment being replaced.
How to change the whole view of a fragment with other fragment !!
Or how to close the current fragment with another fragment, please explain with layout also
Thanks in advance...
You can either add or replace fragments in your activity. Create a FrameLayout in activity's layout xml file.
Then do this in your activity to replace fragment. You can use same code each time you want to replace one fragment with other.
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.container,YOUR_FRAGMENT_NAME,YOUR_FRAGMENT_STRING_TAG);
transaction.addToBackStack(null);
transaction.commit();
If you want to add fragment instead of replace then do this:
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container,YOUR_FRAGMENT_NAME,YOUR_FRAGMENT_STRING_TAG);
transaction.addToBackStack(null);
transaction.commit();
When you want to replace added frogment with anu other fragment then you have to remove previous fragment first (or you can hide previous fragment; depends on your requirement). See following code:
Fragment fragment = getSupportFragmentManager().findFragmentByTag(YOUR_FRAGMENT_STRING_TAG);
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
See following related questions on SO:
Difference between add(), replace(), and addToBackStack()
Basic difference between add() and replace() method of Fragment
Difference between add() & replace() with Fragment's lifecycle
Or see my answer to a similar question:
How to start Fragment from an Activity
getSupportFragmentManager().beginTransaction().replace(R.id.fragmentlayout,new fragment()).commit()
This will help you replace your existing fragment in view with id FragmentLayout with a new fragment().
ThankYou i hope this was helpful.
First you take one Framelayout in Your Activity where you add fragment.
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.framelayout,fragment_1);
transaction.addToBackStack(null);
transaction.commit();
When you replace first fragment with second one you write, just change fragment_1 to fragment_2
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.framelayout,fragment_2);
transaction.addToBackStack(null);
transaction.commit();
In my MainActivity in onCreate method I add() MainFragment to FrameLayout main_view_container:
if (savedInstanceState == null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.main_view_container, new MainFragment(), MainFragment.FRAGMENT_TAG);
fragmentTransaction.commit();
}
In my MainFragment I have ViewPager with FragmentStatePagerAdapter and every page is Fragment itself (PagerFragment).
Then at some point after button click I want to replace whole MainFragment with another Fragment (ReplacementFragment) and add transaction to back stack so I can go back to MainFragment on back button pressed. So I do the following:
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_view_container, new ReplacementFragment(), null);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
After I commit transaction MainFragment is stopped and onDestroyView() is called but completely nothing happens with PagerFragments (that are in ViewPager in MainFragment) Not event a single onStop() call. Then when I go back MainFragment's View is recreated in onCreateView() which means new Instance of ViewPager as well, but still nothing with PagerFragments.
How is that possible that in parent Fragment onDestroyView is called but not in children Fragments?
You must use getChildFragmentManager() when creating pager adapter inside MainFragment.
I have a 3 fragments in an activity when the a tablet is held in portrait. However I only have 2 of these fragments when in landscape. The problem I am having is when going from portrait to landscape the activity is creating the 3rd fragment. I receive and error as this fragment cannot be created.
I have worked out that this fragment is being created because it is in the back stack.
I have tried to remove the fragment in the onDestroy method by using
FragmentTransaction f = fragmentManager.beginTransaction();
f.remove(mf);
f.commit();
However the I get an error saying that I cannot use this function after the onSaveInstanceState
What would be the correct way of taking this fragment out of the back stack?
Update
I should probably add that the fragment I am having problems with is a mapFragment from this libary
https://github.com/petedoyle/android-support-v4-googlemaps
The way I use it is like so
mf = MapFragment.newInstance(1, true);
ft = fragmentManager.beginTransaction();
ft.replace(R.id.mapContainer, mf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack("map");
ft.commit();
You add to the back state from the FragmentTransaction and remove from the backstack using FragmentManager pop methods:
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(myFrag);
trans.commit();
manager.popBackStack();
I created a code to jump to the desired back stack index, it worked fine to my purpose.
ie. I have Fragment1, Fragment2 and Fragment3, I want to jump from Fragment3 to Fragment1
I created a method called onBackPressed in Fragment3 that jumps to Fragment1
Fragment3:
public void onBackPressed() {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-2).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
In the activity, I need to know if my current fragment is the Fragment3, so I call the onBackPressed of my fragment instead calling super
FragmentActivity:
#Override
public void onBackPressed() {
Fragment f = getSupportFragmentManager().findFragmentById(R.id.my_fragment_container);
if (f instanceof Fragment3)
{
((Fragment3)f).onBackPressed();
} else {
super.onBackPressed();
}
}
you show fragment in a container (with id= fragmentcontainer) so you remove fragment with:
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
fragmentTransaction.remove(fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
In case you ended up here trying to figure out how to remove fragment(s) from backstack and you are using Android Jetpack Navigation component you could just use app:popUpTo and app:popUpToInclusive in action node of navigation graph xml to specify fragments that you want to pop out of back stack.
https://developer.android.com/guide/navigation/navigation-navigate#pop
Check this too
https://stackoverflow.com/a/51974492/4594986
What happens if the fragment that you want to remove is not on top of the stack?
Then you can use theses functions
popBackStack(int arg0, int arg1);
popBackStack(String arg0, int arg1);