I use a holder activity with FrameLayout.
There I put a fragment with a listview. It works fine.
ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragments, feedFragment);
ft.commit();
Then I add another fragment.
android.support.v4.app.Fragment targetFragment = new MainPhotoFragment();
ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragments, targetFragment);
ft.addToBackStack(null);
ft.commit();
Here I use add() instead of replace() to return to previous position of the listview when hitting back key. It works fine.
But it is possible to navigate to the third fragment from the second fragment.
android.support.v4.app.Fragment targetFragment = new FullPhotoFragment();
ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragments, targetFragment);
ft.addToBackStack(null);
ft.commit();
Here I use replace to force the 2nd fragment to reload when hitting back key.
Sometimes back key from the third fragment works fine, it displays the second fragment that is reloading on appearing.
But sometimes (as I can see it happens first time when I try this steps) hitting back key from the third fragment leads me to the first fragment, closing the second fragment against my expectations. And the first fragment is reloading.
How to prevent this strange behavious?
add() method will add Fragments to Container and any other fragments added to the Container will be queued back of the first fragment. They will be not visible until and unless first fragment made Invisible. I hope this is the problem you are facing. It would be good if you use replace() for the first-->second fragment navigation also.
Related
I'm using multiple fragments inside an activity like this flow: Fragment A has a list on it's item click Fragment B opens and it also has a list opens Fragment C which has a list Open another Activity , The problem is when I go back from the other Activity I found Fragment A is opened, How I restore the last Fragment C when go back from the other activity?
here is the code of replacing Fragment inside my activity
protected void showFragment(Fragment fragment) {
String TAG = fragment.getClass().getSimpleName();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container_home, fragment, TAG);
fragmentTransaction.addToBackStack(TAG);
fragmentTransaction.commit();
}
replace removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView being invoked. Whereas add retains the existing fragments and adds a new fragment that means existing fragment will be active.
Use add instead of replace
fragmentTransaction.add(R.id.container_home, fragment, TAG);
I had the same issue solved using the above code.
You can use
fragmentTransaction.addToBackStack(null);
instead of,
fragmentTransaction.addToBackStack(TAG);
Hope Your problem will solve.
I wanted to know how I can get the Fragment which is onloaded on my Acticvity.
The background behind this is, that I want to change the onBackPressed method that it's switching to the right fragments. At the moment when I press "Back" the app closes, because I work alot with fragments.
Use addToBackStack on your fragment transaction. This way when you press the back key the transaction gets rolled back and thus your fragment disappears.
I got a solution for the problem:
Fragment fragment = new Fragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.add(R.id.Layout,Fragment);
fragmentTransaction.addToBackStack("flow1");
fragmentTransaction.commit();
On navigating from one fragment to another which are part of same activity, I am using slide animation.
WebFragment fragment = WebFragment.newInstance(Globals.TGURL_CREATE_ACTIVITY, "");
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.enter_anim, R.anim.exit_anim);
transaction.replace(R.id.fragment_activity_layout, fragment);
transaction.addToBackStack(null);
transaction.commit();
This code ensures that when I come back to the first fragment, animation is there.
Well this has been a boon for me so far. But in one specific case it is becoming a curse. The activity is placed on ActionBar tab. When the 2nd (WebFragment) is the current one, and I tap the tab and not the back button, I want the first fragment to be displayed without any animation.
But it has been impossible for me to do this so far as the navigation is inheriting the animation which was earlier given.
This is what I am doing for going back :
TabActivity.this.getSupportFragmentManager().popBackStack();
Working with fragments I've always used replace() for my transactions, but I wish I didn't have to save instance states anymore to restore a fragment's view and prevent reloading when coming back to that fragment. So, I've decided to work with add(). The thing is when I add another fragment, the previous fragment view remains in the background and that's fine (that's the behavior I expected), but the problem is I can actually interact with the views in the background. Example:
Fragment A has a Button
Fragment B has a TextView
When I add Fragment A and later add Fragment B, I'm able to click on Fragment A's Button, even staying on Fragment B's view.
I'm using:
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction().
add(getRootViewContainer(),fragment,fragment.getClass().getSimpleName());
if (shouldGoBack)
fragmentTransaction.addToBackStack(fragment.getClass().getSimpleName());
where getRootViewContainer() returns the id of the FrameLayout I'm using as my activity main container.
Now, is it really the default behavior of add()?
If so, is there a proper way to avoid this or one just has to use replace()?
What you can do here is just hide previous fragment at the time of transaction of current fragment.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment newFragment= new MyFragment ();
ft.hide(CurrentFragment.this);
ft.show(newFragment);
ft.commit();
It worked for me just try it.
FragmentTransaction.hide(fragmentBehind); //works for me!
example :
//I have it globally available
FragmentTransaction trans = MainActivity.getManager().beginTransaction();
//not globally
FragmentTransaction trans = getFragmentManager().beginTransaction();
MapFragment newFragment = new newFragment();
trans.add(R.id.fragmentContainer, newFragment, tag);
trans.hide(this);
trans.addToBackStack(tag);
trans.commit();
Yes, this is a default behaviour of add().
If you really don't want to user replace(), you can try to disable views which are inside "old" fragment.
I'm currently using a ViewGroup (SwipeyTab implementation) to switch between Fragments. However, some Fragment "pages" get replaced by other Fragments on the same Tab, so I initially tried:
FragmentTransaction ft = fragment.getFragmentManager().beginTransaction();
ft.remove(currentFragment);
ft.add(newFragment,"");
ft.commit();
That code would remove the current fragment but not add newFragment (from Logcat, it would get instantiated but not appear).
I ended up adding it in the FragmentPagerAdapter.getItem(int position) call based on current state (based on this: Replace Fragment inside a ViewPager). However, I'd like to be able to add each newly replaced fragment to be part of the back stack.
I tried adding to backstack before removing the fragment:
currentFragment.getFragmentManager().beginTransaction().addToBackStack(null).commit();
FragmentTransaction ft = fragment.getFragmentManager().beginTransaction();
ft.remove(currentFragment);
ft.commit();
and that didn't work - it added the last fragment to the backstack, so when I pressed back, it would just reload the current fragment.
Is there anyway I can add a fragment to the backstack that has been replaced in the "non traditional" way?