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.
Related
I have a simple activity with two fragment: main (contains a list of items) and detail. Details screen is a fragment, which is displayed when an item is clicked in main list. DetailFragment is being shown using replace().
After navigating back from detail screen I would like to have exact same scroll position in RecyclerView that I left it with.
As long as replace() initiates onDestroyView() and onCreateView() cycle to happen for MainFragment, after coming back from DetailFragment the RecyclerView has a scroll position of 0 (at the top), because this is a brand new RecyclerView which has no connection to the one that was there before leaving to DetailFragment.
replace()ing fragment does not initiate onSaveInstanceState() to be called, that's why using techniques outlined here are not applicable.
I wonder what is the correct way of handling this use-case?
Of course I can save the position on onDestroyView() and later manually scroll to that position, but maybe I'm missing some obvious solution?
An answer, that will propose to use add() instead of replace() is not welcome.
I've had RecyclerView declared as a child of NestedScrollView. This was the issue.
When I got rid of NestedScrollView everything was handled automatically.
As onSaveInstanceState() is not possible, try using ViewModel to save the required data.
When you declare and set the adapter to your first recyclerview, try having a call back to your actvity passing the adapter instance , where in your activity you can try saving the adapter instance or any required data in the ViewModel of your activity.
Once you come back from your details fragment you can get the saved instance of your reycycler data from the activity`s ViewModel.
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)
I am working on a application for which I have some issues with fragments. First of all , I want to know if it is possible to make one fragment inside another fragment. And the second one is when to call onCreateView() and onActivityCreated() and which is best?
Per the Android sources:
onCreateView is called by the Activity during the construction of the view hierarchy. This is where the Fragment has the opportunity to instantiate its own user interface view.
onActivityCreated is called when the Activity has been fully created and finished instantiating the view hierarchy. At this point it's safe for the Fragment to access the its views and restore itself from some saved state.
You cannot create a fragment inside another fragment. You should communicate between fragments thru activity.See http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
I didn't understand your second question clearly. But I generally leave onActivityCreated() blank without changing it. And use onCreateView() in a similar way with onCreate().
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.
I really,really need a serious help over here.
I am creating an android app which uses PagerAdapter to create Fragments in an activity. Different Fragment consists of different views according to need which are created during run time. In the last fragment, I have created a sort of "Submit button", which when clicked, is supposed to get user entered values from each views(like EditText) from all Fragments.
I am using following command to get the views(int the above mentioned button clicklistener):
EditText e = (EditText) (getActivity().findViewById(i));
But its not geting the view with that ID except of last two fragments.
So, I am assuming that, it is saving the state of only last two fragments in that activity.
So, How can I save the 'view states' of all the fragments in the activity??
And Isn't it so that, when a view is created in a Fragment, and is added in its layout , that view is also added in the main activity layout?? Am I understanding it in the wrong way??Please let me know.
To simplify it, my question is:
How can we save the contents, entered by users, in dynamically created EditText in Fragments, created using the ViewPager (So that it can be accessed later)??
When you add a fragment to a FragmentPagerAdapter (assuming you haven't written a custom pager) it is added to the FragmentManager. The Fragment manager is independent of the activity lifecycle so it retains the fragment state.
If you take a look here: http://code.google.com/p/ratebeerforandroid/source/browse/trunk/JakeWharton-ActionBarSherlock/library/src/android/support/v4/app/FragmentPagerAdapter.java?spec=svn42&r=42
You can get an idea of how it works. If you want to save the fragment state for another session you'll need to pull back each fragment (getItem) and either use the onSaveInstanceState or write your own custom function
Hope that helps