When I tried to use transitions with fragments using similar code from this article on Medium GitHub. It wouldn't work when I am using the add method() on fragment manager but it would work with replace().
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.addSharedElement(mSharedElement, "transName")
.add(D.id.content_frame, fragment, FRAG_NAME)
.addToBackStack(null)
.commit();
I need to use add() method to keep the fragment below as the user will be navigating back and forth between the first fragment which contains a list of items and the second fragment show detailed info about the item. I don't want to keep loading the fragment with the list again.
Is there a way to get shared element transitions to work when using add() on the fragment manager, than replace().
Related
I've done some research but I really couldn't find the answer.
I have single activity with side menu, and holder. I have many (non support) fragments, and all of them are using same holder (one at a time).
When user uses menu (it's in main activity), and goes another page, I want to add name of the current fragment to backstack (using .addToBackStack(Fragment1.class.getName())), but I couldn't find how to get current fragment.
I don't want to implement interface etc to keep track of current fragment. There is a super simple way using fragmentManger isn't there?
You can get your current fragment like this:
if (getFragmentManager().getBackStackEntryCount() > 1) {
Fragment f = getFragmentManager().findFragmentById(R.id.content_frame);
if (f instanceof BlankFragment) {
// Do something
}
}
OK,
If you want to get latest entry from backstack(thanks to #AndroidGeek);
fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-1);
and, if you want to get currently active fragment (thanks to #Salman500 #AndroidGeek);
Fragment f = getFragmentManager().findFragmentById(R.id.fragment_holder);
you can use this to get fragment id for non support fragment
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_id);
if(fragment!=null)
{
getFragmentManager()
.beginTransaction()
.addToBackStack(null)
.commit();
}
You can keep track of fragments in the main activity (with variables) and access them there. Example:
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction= manager.beginTransaction();
MyFragment myFragment = new MyFragment();
myFragment.doSomething();
Adding to the back-stack:
FragmentTransaction fragment = getSupportFragmentManager().beginTransaction();
fragment.addToBackStack(fragment);
fragment.commit();
This is answered here: get currently displayed fragment
Just use addToBackStack() before you commit() the fragment trancsaction. See it here
So your code will look like :
...
fragmentTransaction.replace(R.id.holder, newFragmentToShow, newFragmentTag);
fragmentTransaction.addToBackStack();
fragmentTransaction.commit();
...
EDIT : after OP was edited
You do not need the fragment class to call addToBackStack() as you have mentioned in the OP. The String argument is an optional string just to keep the state for the backstack state. You should see the documentation
It is all internally managed and the current active fragment is automatically added to the backStack, you may call it from where ever you want, it will always use current active fragment.
I have an Activity that is holding 5 fragments.
One of those fragments is holding 5 more fragments.
if i add to the fragmentManager a .addToBackStack(null).
the back button returns to the last fragment from the activity and not to the last fragment from the "father" fragment (that is holding 5 more fragments).
Any help please..
EDIT:
ACTIVITY:
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().
replace(mainContent.getId(), currentFragment)
.addToBackStack(null)
.commit();
FRAGMENT:
fragmentManager = getChildFragmentManager();
fragmentManager.beginTransaction().
replace(mainContent.getId(), currentFragment)
.addToBackStack(null)
.commit();
This is probably the bug mentioned here: https://code.google.com/p/android/issues/detail?id=40323
You can workaround it by handling the 'back' manually. Refer to this thread for a lot of workarounds: Android 4.2: back stack behaviour with nested fragments
I think the issue might be with "the fragmentManager" here. There is more than one FragmentManager.
There is the FragmentManager for the Activity – Activity.getFragmentManager().
And there is the FragmentManager for child Fragments within a Fragment – Fragment.getChildFragmentManager() or Fragment.getFragmentManager().
Let's say you have an activity, a parentFragment and a childFragment. So, instead of activity.getFragmentManager(), I think in your case, you might want either childFragment.getFragmentManager() or parentFragment.getChildFragmentManager().
Note that if you are using the Support package, the names may be different.
I have two fragments, A and B. Before, A and B were both top level and when I wanted to move from one to the other, I would use something like
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, BFragment.newInstance(), B_TAG)
.disallowAddToBackStack()
.commit();
Now the client wants that from B, hitting the back button, the app goes to A, so I needed to make B a child of A and therefore the transition looks like
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.container, BFragment.newInstance(), B_TAG)
.addToBackStack(null)
.commit();
and from B to A
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.executePendingTransactions();
fragmentManager.popBackStack();
fragmentManager.executePendingTransactions();
The problem is that if the user changes something in B, A still has the old data.
Is there a way of knowing that I arrived at A by clicking the "back" button and poping it from the backstack so I can refresh the data?
Also, do you see a better way of handling the movement between these two fragments?
I would store the common data either:
In a singleton that handles persistent state in the application if that data can be of interest withing the whole application
In a data fragment (a fragment without any UI) that each of your UI fragments can access and change the data.
Then in each UI fragment, you can update the views when resuming the fragments.
I'm using a ViewPager together with a FragmentPagerAdapter to host four different fragments.
What I'm trying to achieve is to successfully replace Fragment1 with a whole new fragment, newFragment,on click of a button.
When I use..
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment1_layout_id, newfragment);
transaction.remove(fragment1);
transaction.commit();
The fragment is replaced and Fragment is shown instead of Fragment1. Though as soon as I swipe all the way to Fragment4 and then back to newFragment, Fragment1 has made a comeback.
Your fragments are provided by FragmentPagerAdapter.
You would need to adapt what fragment your FragmentPagerAdapter creates for your Fragment1 and then call notifyDataSetChanged() on the adapter.
With your approach, the time Fragment1 should be shown again, the ViewPager will simply ask your FragmentPagerAdapter to re-create the specific instance - which will give you back the instance you were trying to replace.
Not that ViewPager can cache fragments internally, as long as notifyDataSetChanged() was not called on the adapter. Hence, it may not pick up chances you have made without that call.
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?