Android Layout is overlapping itself - android

I am using fragments in my app. Below is the screenshot of my app. Everything looks fine on activity launch. But, when I change the screen orientation, the layout overlaps itself while scrolling. Any ideas what is wrong?
EDIT (Solution):
I found out what was wrong. A new fragment was added on orientation change. I was previously using fragmentTransaction.add(...), I replaced it with replace method.

For future vistor's understanding...
You are most likely adding your fragment in your activity's onCreate().
When your device is rotated, your activity is destroyed and re-created, but it also recreates any added fragments.
With these two things in mind...
onCreate is called and you add a fragment to your activity. You have one fragment.
You rotate the screen.
The activity is destroyed and re-created. Your fragment is destroyed and recreated. You still have one fragment.
Your activity calls onCreate() as a part of its recreation, which adds a fragment to your activity. You now have two fragments.
If one or both of your fragments have transparent backgrounds, both may display at once, as is likely the case here.
Either use replace instead of add (which you have done), or better, only add the fragment in onCreate() if savedInstanceState is null. If it is null it means it's the first onCreate() call.

Related

Does adding fragments with tags cause them to not be destroyed when their parent is destroyed?

I have an android application that uses one activity and a number of fragments to build a ui dynamically
The base activity has a simple LinearLayout in it that has nothing (BaseActivity)
I add a fragment to it that only contains a drawer layout with an actionbar a framelayout and a navigation bar (BaseFragment)
To that I add one of two fragments, one shows all children as lists (SerialFragment) , the other in a wizard style (WizardFragment)
Each of those can add one (in case of a wizard) or many (in case of a list) fragments (QuestionFragment)
When I navigate away from BaseActivity then the BaseFragment's onDestroy() gets called, but not the onDestroy() of any of the child fragments
I add the child fragments like so
FragmentTransaction trans = parent.getFragmentManager().beginTransaction();
set_default_animation(trans); //this just adds a custom animation
trans.replace(R.id.wizard_content, QuestionFragment.NewInstance(),question_id.toString()); //in case of a wizard
trans.add(R.id.list_content,QuestionFragment.NewInstance(), question_id.toString());//in case of a list
trans.commit();
The only difference between the BaseFragment (which gets destroyed) and the others, is that in the others I add a tag to them (section_id or question_id) so that I can retrieve them using findFragmentByTag.
Yet when the user navigates away from the activity only BaseFragment's onDestroy() is called.
Is the reason for this the fact that , that fragment is the only one I haven't added using a tag?
Note that I am not using a support fragment manager, the normal one, so I use tags to locate the fragments I want , since the non-support fragment manager does not contain getFragments().
Also note that I have not set the retain instance flag to true on any of the above mentioned fragments
I could test the above by removing tags and adding references to the fragments on the parents, but that means a LOT of refactoring which I would like to avoid if that is not the problem.
Thanks in advance for any help you can provide
After refactoring everything, it seems that the tags weren't the problem (though I still removed them)
What fixed it for me, is using getChildFragmentManager() instead of getFragmentManager() to update the gui
That way when the base view gets destroyed its children are removed aswell
Hope it helps someone

Advantage of fragments on Screen rotation

I wonder if there is any advantage of fragments, on screen rotation.
Generally fragments get destroyed followed by activity. Is there something that fragments retain while doing so?
onDestroy() method is called both in the activity and fragments.
I can try to figure out advantage of Fragment on Screen rotation.
Realtime app problem is:
Android is the potentially frequent destruction and reconstruction of an Activity. The most common time this occurs is when the user rotates the device between horizontal and portrait orientations (Screen rotation).
This crashing usually occurs because device orientation changes cause the Android framework to tear down the displayed Activity along within any contained Views, and then to fully reconstruct the Activity/View hierarchy. Any references to the Activity or to the Views within the Activity suddenly become invalid. Similarly any references within the Activity or Views that were set as a result of a user action or similar are now lost.
There are a number of ways to deal with this issue but one of the easiest is to take advantage of Fragments.
Things to keep in mind:
Fragments won’t automatically resolve this issue because, by default, when the Activity is torn-down in response to an orientation change the Fragment contained within the Activity is also torn down along with any contained Views.
The solution lies in an underused method: Fragment.setRetainInstance with a value of true.
why?
Calling setRetainInstance with a value of true causes Android to preserve the Fragment across the teardown/reconstruction cycle of an Activity. Along with the Fragment, the Views or other object references contained within the Fragment or Views remain.
With setRetainInstance(true) called on a Fragment instance.when an orientation change occurs, Android…
Holds a reference to the Fragment instance
Tears down the old Activity instance
Creates a new Activity instance
Attaches the preserved Fragment instance to the new Activity instance
you must add
android:configChanges="keyboardHidden|orientation|screenSize"
in parent Activity also calling
setRetainInstance(true)
in onCreate of fragment

Why shouldn't use setRetainInstance if I use DialogFragment in order to keep the dialog displayed after configuration changes ?

just need to figure this out. We all know that fragments are attractive in such situations where configuration changes like screen orientation change occur.
This is because Fragments are retained across Activity destruction and recreation and attached to the newly created Activity almost every time if there's a call to the setRetainInstance(true) from the onCreate() Fragment method.
So why it is not the same for the DialogFragment? I mean even if there's no call to the setRetainInstance(true) the dialog is retained across Activity's configuration changes.
Could someone explain me this little difference between a Fragment and a DialogFragment?
Thanks!

Fragment LIfecycle in Custom Tab View

I have a custom widget that performs FragmentTransaction.replace when buttons are pressed. Currently, my code is set up such that the first time a fragment is created, it attaches a bunch of stuff to the view that isn't originally part of the xml layout file.
When the app first launches, all my fragments show stuff correctly, however, let's say I start on Fragment A. I can then transition to Fragment B (with B showing up correctly), however, when I transition back to Fragment A, all the stuff I have attached to the view of Fragment A is now gone. I know this happens because onCreateView is called which probably means the Fragment's view is re-generated when FragmentTransaction.replace is called.
Is there a way where I can keep my fragments around instead of having them re-generate their views when FragmentTransaction.replace is called?
Thanks!
Instead of using fragmentTransaction.replace, use fragmentTransaction.show and fragmentTransaction.hide.
That will keep your fragments from being destroyed.

Bugs in fragments declared in xml layouts (ACL v4)

Being frustrated about fragment behavior, I started doing some testing.
I have one activity and 2 fragments. Fragment A is declared inside the xml layout of the activity and Fragment B is added (only if it's not present) in the layout of the activity in activity's onCreate() method. I've added logging in all of the main lifecycle methods for the activity and the 2 fragments and tested the behavior when switching orientation back and forth. Here are my findings:
Fragment B (the dynamically-added fragment) behaves as expected:
a) after an orientation change, the savedInstanceState bundle contains what has been previously saved in onSaveInstanceState()
b) if setRetainInstance(true), during an orientation change, onDestroy() is not called and also the subsequent onCreate() is not called. The fragment's fields are preserved during the orientation change
Fragment A (the fragment defined in the xml layout) doesn't behave as expected:
a) after an orientation change, the savedInstanceState bundle is always null although onSaveInstanceState() has been properly called
b) if setRetainInstance(true), during an orientation change, onDestroy() is not called as expected BUT, contrary to what is expected, onCreate() is also called when the fragment is being reattached. And also, the fragment's fields are not preserved.
To sum up, for fragments declared inside xml layouts and using ACL v4, saving state during orientation changes does not work and setRetainInstance(true) does not work.
My question is if someone tested this functionality on Android 3.0+ and can say if fragments work correctly when using fragments from Android SDK.
One workaround to this problem would be to always dynamically create my fragments. Did anyone find a different workaround?
Revision 4 of ACL fixed these issues.

Categories

Resources