Nested fragment and back stack - android

I have a fragment in which there is a nested fragment which I add in this way:
if (home == null) {
home = new MyFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(MyFragment.class.getName());
transaction.add(R.id.child_fragment, home).commit();
}
When I enter another fragment and go back the child fragment from above is not there. I checked and the instance is different from null.
UPDATE: I changed the code as suggested by Ashwin S Ashok but it's still not working.

Try using these methods:
// Use this if you don't want to retain the fragment.
protected void replaceFragmentStack(int container, Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(container, fragment);
fragmentTransaction.commit();
}
// Use this if you want to add the fragments in a stack.
protected void addFragmentStack(int container, Fragment fragment, String tag) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.add(container, fragment, tag);
fragmentTransaction.addToBackStack(tag);
fragmentTransaction.commit();
}

I would suggest you to use getChildFragmentManager() when making transactions inside a fragment. And its a bug i guess.
You can check out this thread it will help you alot Android 4.2: back stack behaviour with nested fragments
Also you need to go through The Curious Techizen's blog
Here is the link for the github project sample for same mechanism
I hope this will help you.

Related

Add only one instance of fragment into backstack

I have implemented fragments in my application. Here my code for swiching fragment in fragment_container.
private void switchFragment(Fragment fragment, boolean isAddToBackStack, String tag)
{
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, fragment, tag);
if (isAddToBackStack)
ft.addToBackStack(tag);
setCurrentTopFragment(Integer.parseInt(tag));
ft.commit();
}
I have 4 fragments A,B,C and D and for switching between this fragmnets I am using above method. I have A,C,B in my backstack. If again I switch to fragmnet A, my backstack is like A,C,B,A. What I actually want is If I swich to A again I want backstack sequence like this C,B,A. Means Remove old instance from backstack and add new to it.
First get the back-stacked Fragment by id which you need to remove:
Fragment fragment = getSupportFragmentManager().getFragment(new Bundle(), TAG_KEY)
or there are several methods getBackStackEntryCount(), getBackStackEntryAt. After getting the fragment which you need to remove. Remove it from the fragment back-stack.
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(fragment);
Then you can add a new fragment Done :)

PopBackStack is not working properly

I have coded like this:
FragA >> FragB >> FragC >> FragD
When I press onBackpress() of FragD it goes to directly on FragA but i want to keep it go FragC.
BackPress Code here :
if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 0) {
back_btn.setVisibility(View.GONE);
getActivity().getSupportFragmentManager().popBackStack();
}
Replacing Fragment Code :
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentA fragmentA = new FragmentA();
fragmentTransaction.replace(R.id.framelayoutinner, fragmentA);
fragmentTransaction.addToBackStack("fragmentA");
fragmentTransaction.commit();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentA fragmentB = new Fragmentb();
fragmentTransaction.replace(R.id.framelayoutinner_2, fragmentB);
fragmentTransaction.addToBackStack("fragmentB");
fragmentTransaction.commit();
You are using nested fragments, if you load fragment from another fragment then it become nested structure. So try to check if any child fragment exist within your Root fragment then pop that child fragment first.
Use getChildFragmentManager() for that and make recursive calls till you get most young child fragment(Last added). Or better use Tag on your fragments.
You need to add every fragment into backstack using addToBackStack method
public void setmFragmentContainer(Fragment fragment)
{
final String tag = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.layout_content, fragment, tag);
transaction.addToBackStack(tag);
transaction.commit();
}
This method may help you

How to change the current fragment view with other fragment

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();

List view reload when back pressed in fragment

I have Fragment XYZFragment where i display the list view.On the Listview item click i replace the Fragment like this.
Fragment fragment=new XYZFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft= fragmentManager.beginTransaction();
ft.addToBackStack(null);
ft.replace(R.id.content_frame, fragment).commit();
But my problem is when i click back button the fragment reload the listview.It is never happen when i used to use Activity.
So my question is how to save the instance of previous fragment so that it will prevent the reloading of Data.
without seeing your code we can't help you out but from your question i can figure out the problem, this solution may help you out.
create stack such that
private static Stack<Fragment> myFragStack;
myFragStack = new Stack<Fragment>();
//To Load the fragment
public void loadFragment(Fragment fragment){
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
myFragStack.lastElement().onPause();
ft.hide(myFragStack.lastElement());
myFragStack.push(fragment);
}
//onBackPressed
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (myFragStack.size() > 1) {
ft.remove(myFragStack.pop());
myFragStack.lastElement().onResume();
ft.show(myFragStack.lastElement());
ft.commit();
}
}
It's a sample code.. you can change it as per your requirement.
ft.replace() will completely remove the view & will lose the context so you can't maintain your list state, but using stacks maintaining fragments with hide-show will solve your problem.

How to show second fragment from first fragment with in a single activity

I am developing a simple android app only for tablets and using android 4.0. My application have the main screen like as follow:
Oncreate() of Main Activity I am adding Fragment A in the main.xml using following code:
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment imageFragment = new ImageFragment();
ft.replace(R.id.fragment_container, imageFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
This fragment A just have only a Image view which is clickable. Now I want that when user click on Image view then another fragment (Fragment B) should call and it replace the image view. The Fragment B have a VideoView which play the video.
So My second screen should be like as follow:
My problem is I am not gettting "How to call second fragment from the first one with in main screen activity?"
I can use different activities but I do not want to do so and just want to run this using fragments.
Please guide me.
This is the simplest way:
1) Inside YourActivitycreate a method:
public void goToSecondFragment(){}
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment secondFragment = new SecondFragment();
ft.replace(R.id.fragment_container, secondFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
}
2) In your first fragment, when you want to replace it, call:
YourActivity activity = (YourActivity) getActivity();
activity.goToSecondFragment();
You can do the same using below:
Adding a fragment with maintaining a back stack
FragmentManager supportFragmentManager = getSupportFragmentManager();
supportFragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
}
});
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.addToBackStack("fragmentTag");
fragmentTransaction.replace(R.id.slate, fragment, "fragmentTag");
fragmentTransaction.commit();
And Replacing a fragment
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.replace(R.id.slate, fragment, "fragmentTag");
fragmentTransaction.commit();
Should work for you.

Categories

Resources