Okay I know this has been asked previously but just hear me out !
ISSUE
I want to save state of a fragment and then retrieve it in onCreateView method .
I have a ViewPager in my MainActivity with Four Fragments in it .
I have used viewpager.setOffscreenPageLimit(2) so fragments does not get recreated if am in any of two adjacent fragments but if i am in my first fragment and i go to fourth one then fragment first gets recreated .
and if save it in onSaveInstance inside fragment then that does not get called until host activity's same method is not called , which will not get called if am just swiping between fragments
Answer here also has same problem , it is saving fragments in host activity's onSaveInstance method .So i know how to save fragments state and retrieve it if my host activity gets recreated but what if only fragments gets recreated ?
So How can i save state of a fragment without depending on host activity and then retrieve it in onCreateView method of fragment ?
UPDATE
Just realized how dumb a person can be , data was there all the time i was not just refilling the views with it .
Thanks in advance.
Related
The setup of my project is as follows
Activity has Fragment and it has ViewPager with pages supplied by FragmentStatePagerAdapter.
The data displayed by ViewPager is fetched from network.
When Activity is destroyed and restored, it tries to restore the Fragment that was visible in ViewPager when the Activity was destroyed. But the Fragment inside the ViewPager tries to access data structures that are not fully initialized, as a result crash happens.
I don't want the Fragment in ViewPager to be recreated.
One way that works is to pass null in super.Oncreate(savedInstance) of the Activity. But it will not allows me to restore state in any of other Fragments also which is not what I want.
What is the correct way to do it?
I have Fragment which I replace by another one. I put transaction to backstack so I can move back later. If I press back button saveInstanceState Bundle of restored Fragment is null in it's methods cause saveInstanceState method of Fragment is actually called when parent Activity instance destroyed. So how I must restore Fragment state after returning it from backstack?
This problem was mostly related to ListViews. I have found a solution in more correct managing of adapter data. I had local mAdapter variable in my Fragment which was created, populated with data and set to ListView in onResume() method of my Fragment. I have found solution in moving this code into onActivityCreated() method.
First of all I'm sorry if this explanation seems unclear, I'm new to Android.
I have a ViewPager in main activity showing fragments added dynamically by user. Fragments are created initially on activity start up and are added to ViewPager via Adapter i.e. adapter simply returns proper fragment and as I understand correctly fragment's content is created at this time when ViewPager 'retrieves' a fragment first time.
The problem is when main activity gets restored after orientation changing all fragments are resurrected as well and when Adapter tries to return newly created by user Fragment method createView() is no longer called and it fails with NullPointerException. It seems ViewPager retains fragments attached to it initially and doesn't call createView() for newly added ones for the same position.
I have a feeling I'm missing vital point on the Fragment lifecycle. I wouldn't like to change the design. My main question is what the correct way is to return a Fragment added to ViewPage after activity is restored? Is there any way to locate recently attached fragments?
If the fragment already exists, it will be re-used. However the state of the fragment will not. You should take a look at http://developer.android.com/training/basics/activity-lifecycle/recreating.html for more information.
In particular you should look at overriding onSavedInstanceState and onRestoreInstanceState as a method to repopulate the field that is generating that nullpointerexception
To determine if an instance of a fragment has already been created you can use 'findFragmentByTag' like so:
String fragmentTag = MyFramgment.getClass().getName();
MyFragment frag = getFragmentManager().findFragmentByTag(fragmentTag);
if(frag == null)
frag = new MyFragment();
Whatever ends up being referenced in 'frag', show this to the user.
I have 2 fragments which are called from the action bar of an activity. Both are gridviews, the first one displays applications with a dedicated adapter, and the second one displays a file list with another adapter. My problem is that when I launch a file then when I back to my activity I switch from one fragment to another, when I come back to the previous one, its content disappears. And when I rotate tablet I have the some problem, because my Fragment restart so for this I think that removing fragment give the possibility to create a new Fragment up to date. How can I save and reload data in my fragment.
How can I manage to update the content of the first fragment while coming back from the second one ? And how to remove fragment after the rotation in order to recreate the Action with new Fragment? I asked this questions but I don't have any responses. the code is given below
If your data is just strings or integers, you can make use of shared preferences to store and retrieve data.
Solution to your first problem -how to save fragment state
Use setRetainInstance(true) in you fragments onCreate() *it prevents your fragment from destroying and hence recreating.
Add your fragment to back stack
declare your adapter globally in fragment and resuse it when you get back.
when, you get back to fragment its onCreateView() method will be called directly. hence initialize your adapter in onCreate() method and use it in onCreateView().
Solution to your second problem -how to update fragment content
For this you can use interface. create interface in your second fragment and implement it in your first fragment. prefer this doc for this,
http://www.vogella.com/tutorials/AndroidFragments/article.html#fragments_activitycommunication
I have 2 Tabs and 2 Corresponding Fragments. On calling the LAUNCH Activity both Tabs were added and then the first one added will be shown. Thus the first Fragments onCreateView is called the second Fragments ones not.
In my case this is an issue because the first Fragment has to call methods on the second Fragment. Inside the second Fragment there is an Objectreference which will be set by calling the onCreateView in the second Fragment.
Therefore I used following code snippet to solve this
actionBar.setSelectedNavigationItem(1);
actionBar.setSelectedNavigationItem(0);
It works but in my opinion there must be another possibility to solve this issue. Like calling the onCreateView of the second Fragment?
Here is the relevant code snippet. The listener is implemented as in android-dev Sample only with small changes not affecting my issue.
simplexFragment corresponds to the first Fragment
graphicFragment corresponds to the second Fragment
// adds two tabs
actionBar.addTab(actionBar.newTab().setText("Input").setTabListener(new TabListener(null, "input_fragment")));
graphicFragment = new GraphicFragment();
actionBar.addTab(actionBar.newTab().setText("Graphic").setTabListener(new TabListener(graphicFragment, "graphic_fragment")));
simplexFragment.setGraphics(graphicFragment); // sets the internal reference!
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// selects the Tab so the GraphicFragments onCreateView will be called
actionBar.setSelectedNavigationItem(1);
actionBar.setSelectedNavigationItem(0);
Thanks for support.
In my case this is an issue because the first Fragment has to call methods on the second Fragment.
This is not how Fragments are meant to work. The idea is a Fragment should be self-contained and re-usable and one Fragment shouldn't know that another exists (or at least shouldn't rely the existence any other Fragment).
For example, suppose you have 3 Fragments and ActivityA uses FragmentA and FragmentB but you have another Activity (ActivityB) which uses FragmentA and FragmentC. In that case, FragmentA doesn't know what the other Fragment is (B or C) and shouldn't even expect there to be another Fragment at all.
The way to achieve what you want is to use callback methods on the Activity and have it perform the actions on any other Fragments (if they exist). It can do this by either calling public methods on the other Fragments or by passing data in the 'arguments' Bundle when it creates the other Fragments.