Detail fragment over listing fragment - android

I have two fragments - Listing and detail. Initially I load the listing fragment in the container of the activity using
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, listingFrag);
ft.commit();
On tapping an item in the listing fragment I load the detail fragment using
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.content_frame, detailFrag);
ft.addToBackStack(null);
ft.commit();
On loading detail fragment I do not get the onPause call of the listing fragment. Neither do I get the onResume call of the listing fragment on coming back from detail fragment (using the system back button).
Also, when I am in the detail fragment, putting the app to background calls the onPause of both the listing and detail fragments. On getting back the app from background, onResume of both listing and detail screens get called.
The above mentioned behaviors are quite unexpected.
I would want
1) listing fragment's onResume to be called on coming back from listing screen
2) listing fragment's onPause to be called on loading detail fragment
3) only detail fragment's onPause to be called when the app is put to background
4) only detail fragment's onResume to be called when the app is brought back from background
Can some one please explain a way to do this.
Thanks in advance!

onPause and onResume in fragment are just the reflection of onPause and onResume in Activity.
So every time you go from one activity to another all the fragments of the first activity will call onPause and all the fragments of the 2nd activity will call onResume.
This functions are not for fragment visible/add or remove.

When you display the detailed fragment, you add it which means that both the listing and the detailed fragments are active at the same time. Hence both of them receive onPause() and onResume().
You should instead try replacing the listing fragment with the details fragment. That will cause onPause() in the listing fragment and only one fragment will be active at a time.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, listingFrag);
ft.addToBackStack(null);
ft.commit();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, detailFrag);
ft.addToBackStack(null);
ft.commit();

Related

How do i get the onloaded fragment?

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

Get fragment from backstack

Hardly can't get fragment from backstack, even start thinking of keeping in in singleton which is probably bad.
Saved to backstack like this and all time try to get it by tag or something gives me error.
Fragment fragment = UserProfileFragment.newInstance(null);
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(FRAGMENT_PLACE_RESOURCES, fragment);
trans.addToBackStack("profile");
trans.commit();
It just return me null here so I can't use this fragment. No logs.
Fragment fragment2 = getFragmentManager().findFragmentByTag("profile");
getFragmentManager().findFragmentByTag("tag")
is only used when you have added a fragment with specific tag for e.g.
fragmentTransaction.add(R.id.order_container,mProfileFragment,"profile");
or
fragmentTransaction.replace(R.id.order_container,mProfileFragment,"sometag");
Then you will be able to find this fragment by the tag.
In your case you are adding a transaction to backstack so you will not be able to find that fragment by tag. You just adding a transaction to backstack thats it not a fragment. And also your fragment was removed from the activity and destroyed so you have to revert the transaction by popping backstack instead of finding that fragment by tag.
You have to call
getFragmentManager().popBackStack("profile");
to get that fragment back to the activity and make it visible on screen.

Android - How to resume fragment from back stack if it exist?

Hello I am working with sliding menu with fragment.
Indivisual fragment works properly. But suppose user navigates From fragment A->B , now 'B' works perfect and now if user goes from B->A than fragment 'A' is called from onAttach() .
I want such a condition if any fragment is opened , than reopening it should not load whole fragment , it should be resumed just like we handle activity with Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
Here is my code...
FragmentManager fm = MainActivity.this.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Layout1 fragment = new Layout1();
ft.add(R.id.activity_main_content_fragment, fragment,Layout1.class.getName());
ft.addToBackStack(Layout1.class.getName());
ft.commit();
Answer updated:
Reading the documentation, there is a way to pop the back stack based on either the transaction name or the id provided by commit. Using the name may be easier since it shouldn't require keeping track of a number that may change and reinforces the "unique back stack entry" logic.
Since you want only one back stack entry per Fragment, make the back state name the Fragment's class name (via getClass().getName()). Then when replacing a Fragment, use the popBackStackImmediate() method. If it returns true, it means there is an instance of the Fragment in the back stack. If not, actually execute the Fragment replacement logic.
private void replaceFragment (Fragment fragment){
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}
If you return to a fragment from the back stack it does not re-create the fragment but re-uses the same instance and starts with onCreateView() in the fragment lifecycle, see Fragment lifecycle.
So if you want to store state you should use instance variables and not rely on onSaveInstanceState()
Check this link. it will help How to resume Fragment from BackStack if exists

Android Fragment Unable to go back

I have an app that uses fragments with tabs/viewpager
[Tab 1][Tab 2][Tab 3]
Tab2 has a ListView and in the onClick method of the ListView I am showing a detail view with the following code
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
NextFragment nextFragment = new NextFragment();
transaction.replace(R.id.container, nextFragment);
transaction.addToBackStack(null);
transaction.commit();
The issue is that in the NextFragment when I use the hardware back button the whole app closes?
I'm not sure why it doesn't let you return when back is pressed, but what I've done in my application is the following:
I have overriden the onBackPressed action and created a check that once it is pressed and the user is in the fragment that he wants to return from, just create another fragment transaction to the previous fragment.
I have done so because I needed to update the previous fragment, but I'm sure there is a better way to solve your problem.

Weird android fragment issue using back stack

I have following issue with Android compatibility package fragments.
There is following hierarchy of fragments:
A(login) -> B(dashboard) -> C(details)
Login fragment is added with function:
private void addFragment(Fragment f) {
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.replace(R.id.main_content, f);
ft.commit();
}
After successfull login dashboard is added same way, without adding transaction to backstack. C fragment is added like:
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.main_content, f, id);
ft.addToBackStack(null);
ft.commit();
So basically on detail screen I have logout button, which should bring me to login A and remove all fragments from backstack. According to android developer docs:
Whereas, if you do call addToBackStack() when removing a fragment, then the fragment is stopped and will be resumed if the user navigates back.
But it is not the issue in my case. When logout is pressed in C fragment:
getFragmentManager.popBackStackImmediate();
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.replace(R.id.main_content, new LoginFragment());
ft.commit();
onActivityCreated(), onStart() of B fragment are also called (instead of onResume written in docs), making my code crash because in this fragment Im starting some thread operation, and after adding login fragment I got IllegalStateException that fragment B is not attached to an activity (when thread operation is over it updates fragment UI) Do anyone knows how replace really works and how overcome this problem?
I guess you should call
addToBackStack for each fragment you add giving a different name to them.
Reading your code seems to me you don't do it.

Categories

Resources