Weird android fragment issue using back stack - android

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.

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

Android: Fragments act unexpected (suddenly transparent?)

I have a problem with my fragments. I use this code to navigate between the fragments:
Between the "main" fragments (without backstack, because I want the user to exit when he presses back (it works)):
FragmentManager fragmentManager = getFragmentManager();
final FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_up_honeycomb, R.anim.slide_out_up_honeycomb);
ft.replace(R.id.container, NewsFragment.newInstance(position + 1), NewsFragment.class.getSimpleName());
ft.commit();
and between the "inner" fragments (with backstack):
FragmentTransaction ft = ((Activity) getActivity()).getFragmentManager().beginTransaction();
Fragment nextFragment = LexikonDetailFragment
.newInstance(item);
ft.setCustomAnimations(R.anim.slide_in_up_honeycomb, R.anim.slide_out_up_honeycomb);
ft.replace(R.id.container, nextFragment);
ft.addToBackStack(LexikonDetailFragment.class.getSimpleName());
ft.commit();
But in the following case:
fragment A -> fragment A1
fragment A1 -> fragment B
Press back button (should end the app)
-> goes back to fragment A1
happens:
Image
It looks like the A1 fragment doesnt gets removed from the backstack and stays in the background. I thought one possible solution could be to set to all fragments a white background..but this wouldn't fix the problem, it would just hide it. So what could be a possible solution?
Okay, i found a solution:
I had to remove the inner fragments manualy via the command:
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
I call this command each time my "outer" fragment changes. The inner ones get removed and tada...it works like a charm :)

Navigate back to activity from fragment

I have class Demo and I am extends the demo by FragmentActivity class. Also I have another class Fragment1 extends Fragment. And the onclick of button i am navigate from activity Demo to the Fragment Fragment1. Now I want to come back on Demo from the Fragment1. So how can I back to Demo activity?
Thanks.
Your question is lacking a lot of detail, so I'm taking a stab in the dark here, but...
I presume in your onClick code, you use the Fragment Manager to create a new Fragment Transaction, then add the fragment to that transaction and commit it?
Your problem with the activity being closed when you hit the back button is likely because your fragment was not added to something called the "back stack". You can find to documentation here http://developer.android.com/reference/android/app/FragmentTransaction.html#addToBackStack%28java.lang.String%29, but crucially the main thing you need to do is modify your code to include the line below:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, new Fragment1());
fragmentTransaction.addToBackStack("Transaction ID"); // <-- This is key!
fragmentTransaction.commit();
Once that's done, Android will remember the adding of the fragment as a navigation act, and should reverse the transaction when the back button is hit.
If this wasn't what you're looking for, or if it doesn't work, please provide some more detail and some code samples and I can take another look.
Try adding the fragment you want to go back to manually to the backstack.
FragmentTransaction transaction = getFragmentManager().beginTransaction();
YourFragmentName myFragment = new YourFragmentName();
transaction.replace(R.id.fragment_container, myFragment);
//if you with to add it to backStack, do this, otherwise skip the line below
transaction.addToBackStack(null);
transaction.commit();

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

Detail fragment over listing fragment

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

Categories

Resources