Iterate over all currently loaded fragments in a ViewPager - android

I have a ViewPager. It has Fragments. When those Fragments are created, they load data from the server. When the user selects a menu item, I want to tell those fragments to filter their data without reloading from the server.
To do this, I have a subclass of FragmentPagerAdapter which keeps a List to hold a reference to each Fragment as it is created. When the menu item is selected, I simply iterate over that collection and call a method on each Fragment.
The problem arises when the device is rotated. The framework automatically restores the fragments to their parent view, without calling the getItem method of my adapter, meaning that my List is empty.
How can I either repopulate that List when the device is rotated, or obtain a list of all of the ViewPager's child Fragments without keeping a list?
EDIT: It may be important to note that my ViewPager lives in a Fragment, and that Fragment gets hot swapped via a side navigation menu. In other words, my ViewPager is not owned by an Activity, and there are some known issues about ViewPager not cleaning up its child fragments correctly which may be exacerbating the problem.

Check this link Get Current visible fragment in ViewPager
The author basically suggests 2 similar approaches which are to attach tags on fragment creation and keep track of it.
getSupportFragmentManager().beginTransaction().add(myFragment, "Some Tag").commit();
Then retrieve the tag like so:
int index = mViewPager.getCurrentItem();
String tag = mPageReferenceMap.get(index);
Fragment myFragment = getSupportFragmentManager().findFragmentByTag(tag);

Related

ViewPager Fragment RecycleView Reset

I have 3 fragments in the ViewPager.
PersonalFragment
CropFragment
NotesFragment
Every fragment has a RecyclerView and I was adding items using a dialog in it. However, when I go to the last fragment (i.e. NoteFragment), the first fragment's (i.e. PersonalFragment) RecyclerView gets empty (all items are removed). The same thing happens when I come back to the first fragment, the last fragment's RecyclerView resets (all items are removed).
It is difficult to understand without seeing some of your code which is related. I think you might have implemented the onResume function incorrectly. Each time you go to the third fragment in your ViewPager, the first Fragment needs to be reinitialized and you need to take care of this in your onResume function.
However, another workaround for your problem is setting the off-screen page limit of the ViewPager like the following.
viewPager.setOffscreenPageLimit(2);
Hope that helps.

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.

Fragment doesn't refresh content after returning from back stack

I have a ZooFragment which contains a ViewPager.
This ViewPager has three children: LionFragment, LeopardFragment, and TigerFragment, each of these children can request transaction to call a new ZooFragment.
When a ZooFragment called zooA (with arguments) is initialized, all three children in ViewPager display content. From any child fragment, user touch will call a new ZooFragment called zooB (with different arguments, of course).
Based on transaction action from child fragment to ZooFragment:
1.If I use transaction.replace(), zooB will be blank, all three children in zooB display no content, empty. At zooB, pressing hardkey Back from navigation, zooA becomes empty.
2.If I use transaction.add(), zooB won't be blank, following by a Back button press, zooA gets empty.
In ZooFragment class, I do loading data in onCreateView(), so what is the reason why all the child fragments in ViewPager get empty?
Please do not replace the fragments in the ViewPager, just show (using transaction) in any other contained in the same layout as that of ViewPager and that container should be a FrameLayout. Also device a mechanism to know when and what fragment comes into view. Then request for a fresh data from a utility that responds to update your fragment. I do not think onDestroyed will be called in case of all the fragments in the ViewPager.
Fragments in the ViewPager are fixed, so should there contents will not go till the application manager wants to destroy it.Instead of trying to replace the fragments in the adapter, try to give a different set of fragments and notifyDataSet changed, or take the advantage of FrameLayout to show another fragment over the view pager tab's current fragment.
There is my solution that works:
Swipe Gesture applied at Fragment level along with ViewPager with it's default swipe disabled

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