Leaking Fragments from FragmentManager - android

I'm struggling with a Fragment leak and I am not sure how to handle it:
I have a FragmentActivity(I'm using support lib v4) with two buttons: forth and back. Forth button adds a fragment to the backstack with a long animation and back button pops the fragment from the backstack.
Code for forth button click listener:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.own_slide_in_left, R.anim.own_slide_out_right, R.anim.own_slide_in_left, R.anim.own_slide_out_right);
transaction.add(R.id.fragment_holder, new FirstFragment());
transaction.addToBackStack(null);
transaction.commit();
And for back button click listener:
getSupportFragmentManager().popBackStackImmediate();
When I press the back button and rotate the device while the animation is ongoing then after rotation visually everything seems to be ok, but the previous Fragment is leaked. I can tell it by having a breakpoint in, for example, Fragment's ctor or onSaveInstanceState(). It will be it on each rotation when it shouldn't be.
What am I doing wrong?
EDIT: This problem persists using native Fragments, Android 4.0.3

Related

Issues navigating back with NavigationDrawer

I'm using the Android Studio template for Navigation Drawer, but I just can't figure it out how to properly navigate back from the new Fragments I added to the ones already existing.
I have seen many posts about similar problems, but couldn't fix it with the answers.
Fragment manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
And my many tentatives:
Gets back to an empty screen
transaction.replace(R.id.fl_nav_host_content_main, entitiesFragment);
transaction.addToBackStack(null);
Gets back to an empty screen
transaction.replace(R.id.fl_nav_host_content_main, entitiesFragment);
transaction.addToBackStack("GalleryFragment");
Gets back to an empty screen
transaction.replace(R.id.fl_nav_host_content_main, entitiesFragment, "GalleryFragment");
transaction.addToBackStack(null);
Gets back to an empty screen
transaction.replace(R.id.fl_nav_host_content_main, entitiesFragment, "GalleryFragment");
transaction.addToBackStack("GalleryFragment");
The new Fragment design shows incorrectly. At first does not navigate back; at second does navigate back twice
transaction.replace(android.R.id.content, entitiesFragment);
transaction.addToBackStack(null);
The new Fragment design shows incorrectly. At first does not navigate back; at second does navigate back twice
transaction.replace(android.R.id.content, entitiesFragment);
transaction.addToBackStack("GalleryFragment");
The new Fragment design shows incorrectly. At first does not navigate back; at second does navigate back twice
transaction.replace(android.R.id.content, entitiesFragment, "GalleryFragment");
transaction.addToBackStack(null);
The new Fragment design shows incorrectly. At first does not navigate back; at second does navigate back twice
transaction.replace(android.R.id.content, entitiesFragment, "GalleryFragment");
transaction.addToBackStack("GalleryFragment");
Can someone help?
Thanks in advance.

Fragments and onBackPressed function

I am using a navigation drawer and fragments to inflate the main activity.
However when I press the back button it closes the application which is obvious with fragment setup.
What I want is that when the user clicks the back button they go to the home page fragment if its not currently the view, but if they are on the home page I want the app to close.
How to go around this problem?
Overriding the back button would be a REALLY BAD idea, as it will hurt more than help.
If you want to add a Fragment that will not be replaced (Your initial "HomePageFragment"), just add this line:
transaction.addToBackStack(null);
Which will give you something like:
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, fragment, TAG_FRAGMENT);
transaction.addToBackStack(null);
transaction.commit();
If you add some other Fragments, don't add them to the back stack.
You should override the onBackPressed method in the activity class and using that you can determine whether you need to switch back to your home fragment or call super.onBackPressed().

Not return to dialogfragment after fragment

I have Fragment1. On them, i pressed button and start DialogFramgent. On DialogFragment i pressed button and start Fragment2. When i pressed back, i am return to Fragment1, but not to DialogFragmnet
You can add the fragment to the backstack. A call addToBackStack() should solve the problem. Straight from the documentation: "This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button". See for details:
http://developer.android.com/guide/components/fragments.html
Jasper
A great feature about using fragments in your activity is the ability to add, remove, replace, and perform other actions with them, in response to user interaction. Each set of changes that you commit to the activity is called a transaction and you can perform one using APIs in FragmentTransaction. You can also save each transaction to a back stack managed by the activity, allowing the user to navigate backward through the fragment changes (similar to navigating backward through activities).
You can acquire an instance of FragmentTransaction from the FragmentManager like this:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Each transaction is a set of changes that you want to perform at the same time. You can set up all the changes you want to perform for a given transaction using methods such as add(), remove(), and replace(). Then, to apply the transaction to the activity, you must call commit().
Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.

Why is Fragment.addToBackStack() causing the Back button to do nothing?

Activity 1 is visible. Press a button, and Activity 2 opens.
Activity 2 adds fragment A to itself (and back stack) and it displays fine
Pressing a button within the fragment transitions to another fragment, B
Press Back. Nothing happens. Huh? The Back press is seemingly absorbed and not acted upon, the display remains the same.
Press Back a second time, it reverts to the Activity 1, as expected.
Why is my fragment not being shown in step 4? I've added the fragment to the back stack, so why (when the Back button seems aware of its existence) does it not show the fragment?
Here's the code I'm using in Activity 2 to open Fragment A.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_profile_edit);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
transaction.addToBackStack(null);
transaction.add(android.R.id.content, new MyFragment());
transaction.commit();
}
And here's the code to open Fragment B
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
transaction.add(android.R.id.content, new MyOtherFragment());
transaction.commit();
Have you tried transaction.replace(...) instead of transaction.add(...)? That should work. I'm guessing because if you're just adding a fragment over another, it doesn't see transaction as wanting to go back fro Fragment A.
EDIT
The actual answer for the question is below in the comments: addToBackStack() should be used on the fragment which is replacing, not the one being replaced.

Back key to pop the Fragment shows overlapping fragments

I created a sample app to test this overlapping issue.
I have a fragment type, Fragment1, and I create a new instance of Fragment1 and add it to a FrameLayout in my activity at runtime. I add the fragment with the help of a few buttons.
Note: I have given each new instance of Fragment1 a different number(#1, #2, #3, etc.) to display on the UI to help me figure out which fragment I am viewing.
So.. here is what I do:
Click on Button 3, create new instance of Fragment1 and add it to Frame1.
Click on Button 4, create new instance of Fragment1 and add it to Frame1 and add it to the fragment backstack.
Repeat 1 and 2.
Repeat 1 and 2.
Now, I have fragments in this order: 1(#1),2(#2),1(#3),2(#4),1(#5),2(#6).
I press the back key when viewing fragment #6.
Back key press, UI displays (#5).
Back key press, UI displays (#3 AND #5),
Back key press, UI displays (#1, #3, AND #5)
It seems fragments are getting displayed ON TOP of each other.
WHY? Is there an overlapping issue? How can I clear out this overlapping issue. I thought this would be an issue on the compatibility library... but it is also on 3.0.
Code for adding fragments:
public int doFragmentChange(int cont1, Fragment frag1, String tag1, int cont2, Fragment frag2, String tag2,
boolean addToStack, String stackTag) {
FragmentManager fm = getFragmentManager();// getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (frag1 != null) {
ft.replace(cont1, frag1, tag1);
}
if (frag2 != null) {
ft.replace(cont2, frag2, tag2);
}
// add fragment to stack
if (addToStack)
ft.addToBackStack(stackTag);
return ft.commit();
}
If you perform two add calls one after the other (two commit calls) then yes the fragments will appear overlaid, one on top of the other effectively.
So (for new example) if say you replace frag1 with frag2 and then frag3 with frag4 in the same frame with no backstack transaction then I would expect frag2 and frag4 to be overlaid.
Furtheremore there is also a potential issue in your chaining of replace. You should call a separate commit for each. See Android — Replace Fragment Back Stack With New Stack?.
Just override the onBackPress() or onKeyUp and remove the top fragment.

Categories

Resources