Fragment with fragments inside - retain state - android

I have one fragment that contains two fragments inside.
Every fragment is loading some names from database and displays them as a list with a limit of 50.
At start my adapter has 50 elements, when user scrolls down another 50 is beign loaded, then adapter is with 100 elements.
Now whenever I rotate the device, my data in adapter is messed up, that is my question is there any way to save my state of childFragment? without using parceable and parcel the whole 100 elements together with current position?

You should use Fragment's setRetainInstance(boolean) feature.
Setting
setRetainInstance(true);
to a Fragment containing the child Fragments should do.
Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:
Understanding Fragment's setRetainInstance(boolean)

Related

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

Save state of dynamic ViewPager

I have an android app in which I want to dynamically add and remove Fragments to a ViewPager during runtime, and preserving the Fragments on configuration changes.
Thus far I have implemented a FragmentStatePagerAdapter, holding my Fragments in a list with methods add, remove and replace to manipulate my Fragments. Basically, all they do is insert or delete a Fragment in the list and then call notifyDatasetChanged(). I insert the staring Fragment as a new Fragment during the Activitys onCreate() method.
I know want to preserve my Fragments during configuration changes. Currently, when I change my screen orientation, all my currently Fragments are deleted, and I get back to the starting Fragment, naturally because the Activity is recreated, and the Fragment and the Adapater are reinstantiated during the onCreate() call. I was trying to save the state of the Adapter with the Adapter.saveInstance() during the Activitys onPause(), but when I try to restore it via Adapter.restoreInstance(), I get an empty adapter.
Can anyone give me a hint on what is the correct way in Android to save state a FragmentStatePagerAdapter?
To save the state of the current fragment, i think first of all you will have to check which fragment is currently added/visible in the container activity. Once you have that fragment, simply use onSaveInstanceState() method of the container activity to save the instance of the current fragment.
For code snippet please follow this link.

Custom CursorAdapter loads data from db every time fragment switched

I have an Activity with ViewPager and three Fragments with-in. One Fragment contains ListView with custom CursorAdapter which loads data from database.
I've noticed that my cursor adapter loads data every time I switch Fragments in ViewPager. I think that it's normal and is due to the fact that every Fragment has its own lifecycle.
Regarding this it will be great pleasure for me if the users of the stackoverflow explain about their experience or best practices at all.
Thanks!
ViewPagers maintain the state of only certain number of fragments, which defaults to 1 for both sides of the current selected fragment. For example, if you have 3 fragments, when the first is selected, only first two fragments will be instantiated and have the listview data loaded. Alternatively, if you have the second fragment selected, the first and the third will be instantiated. If you switch to the third fragment, the second fragment will be retained, but the first one will be lost. However, you can set the number of fragments to be retained with calling setOffscreenPageLimit method on viewPager with any number of fragments to retain you need. Though you should remember, that setting the number too high may cause your app to consume too much memory.
For example, if you want your fragment to not reload listview content from db while switching fragments and you have 3 framents in your viewPager, you may write the following code:
ViewPager mViewPager;
mViewPager.setOffscreenPageLimit(2);

FragmentStatePagerAdapter performance issue

I have implemented an activity that displays fragments in a viewpager. The activity initially displays 5 fragments of a given type (type A). Each type A fragment contains a list of information. When a button is pressed, the fragments are replaced with another tpye of fragments, type B (i.e., fragments that use a different layout and display different information are loaded).
I have implemented this with a ViewPager and a custom FragmentStatePagerAdapter. The custom FragmentStatePagerAdapter overrides the getCount, instantiateItem, getItem, getItemPosition, etc. functions and all works fine. When I press the button the views switch from fragment type A to fragment type B. In order to do this I am using a replace fragment transaction and I also call notifyDataSetChanged on the adapter. The switch from type A to type B fragments is accomplished by checking which type of fragment I need to create in the adapter's getItem function. The problem is that the switching process (i.e., changing from fragment type A to fragment type B and vice versa) takes some time (around 2 seconds) - this delay is quite noticeable and annoying.
This occurs because the adapter's getItemPosition function returns POSITION_NONE. When POSITION_NONE is returned, the viewPager recreates the fragment. Furthermore, when the replace transaction is executed, all items of the adapter are removed and all new ones are recreated. The same happens when I switch back to fragments type A.
Does anyone know if there is a better or faster way to do this? Using a FragmentPagerAdapter should not be a good solution since the number of fragments in the viewPager could grow.
I have commented out the updating of the fragments and the problem is gone so the problem is the time it takes to update the fragments. Is there a way to update the fragments asynchronously? That should take care of the problem.
The ViewPager instatiates by default a minimun count of Fragments. In general the left and right one of the current Fragment. So you don't need to care about the total number of Fragments.
You can control the total number with the ViewPager.setOffScreenPageLimit() method.
Also a AsyncTask seems to be a good idea to manage the intensiv work of your Fragments.

How to handle savedInstanceState when using ViewPager?

I'm using android.support.v4.view.ViewPager in an application.
When the user rotates the screen, the activity is destroyed and recreated. The fragments that are currently active in the ViewPager (usually the one on screen, the one to the left of it, and the one to the right of it) are all stored to the savedInstanceState.
A new activity is created, FragmentActivity.onCreate(savedInstanceState) is called with the fragment state, and those three fragments are re-created using the bundle. However, my onCreate also sets up the ViewPager and ViewPager adapter, which create their own fragments afresh, thus resulting in TWO of each of those three fragments.
How can I associate the automatically re-created fragments with my ViewPager's adapter rather than re-creating them from scratch?
Never mind. It appears that I was using FragmentPagerAdapter incorrectly.
The correct way to use FragmentPagerAdapter is to instantiate your new fragment in getItem(). I was instantiating all my fragments in the adapter's constructor instead, storing them in an array, and then looking them up in the array and returning the appropriate fragment in getItem().
If you instantiate your fragment from getItem(), then FragmentPagerAdapter.instantiateItem() will automatically use the recycle fragment instead of instantiating a new one.

Categories

Resources