Nested Fragments and ViewPager issues on Android - android

I am using a FragmentStatePagerAdapter in combination with a view pager, which is nested in a fragment on Android. Thus, I am using the ChildFragmentManager in combination with the FragmentStatePagerAdapter to create my fragments.
So far so good, but here is the problem:
If I open a different Activity without finishing the activity that hosts the fragment with the view pager and afterwards resume it, the fragment that was selected in the ViewPager is empty. If I switch the fragment in the ViewPager before I open the different Activity, this issue does not appear. After returning and seeing the empty Fragment in the ViewPager, I am still able to switch the next Fragments, but if I try to switch back to the empty Fragment, I get a NullPointerException. This issue does not occur if I switch between the Fragment hosting the ViewPager and a different Fragment or if I change orientations.
If I use the FragmentManager instead of the ChildFragmentManager, I do not have this issue when switching to a different Activity, but it will then occur if I switch between the hosting and a different fragment or if I change the orientation.
So here's what I already tried without any success:
* Use FragmentStatePagerAdapter adapter and FragmentPagerAdapter
* Use setRetainedInstance(true and false)
* Use getChildFragmentManager() and getFragmentManager()
* Override getItemPosition() return POSTION_NONE and use notifyDataChanged() in onResume()
The only thing that is currently doing the trick is recreating the PagerAdapter in onResume() and re-initializing the ViewPager, but I think that's really bad practice as everything needs to be recreated.
So is there somebody, who can explain to me how a correct implementation should look like, or why the fragments can become empty (they are not null, I checked that). I am searching for a more elegant solution rather than recreating everything each time I resume my activity.
Any help is really appreciated.

Related

ViewPager inside a fragment is empty when navigating back from another fragment

I've got a viewPager inside a fragment (A). Inside the viewPager there are 3 another fragments. If I replace the fragment A with fragment B and click back, the viewPager appears with all fragments being empty. Scrolling back and forward reloads the first and third fragments.
I googled a lot, some people suggested to pass the childFragmentManager to the FragmentStatePagerAdapter, but if I do this, the app crashes with "
No view found for id ** for fragment **" exception.
I tried to use the FragmentPagerAdapter - same result.
Did anyone come across with this problem and has a suggestion?
Ok, I figured that out. The problem with passing the childFragmentManager was because child fragment doesn't contain the container whose fragment(s) are to be replaced, so the app crashed with "No view found..." exception. However, when replacing the fragment, if I use the parent's fragmentManager, then all works fine! So, instead of fragment.fragmentManager!!.beginTransaction() I now call fragment.parentFragment!!.fragmentManager!!.beginTransaction(). In case someone will face the same problem.

Viewpager with fragment pager adapter and Fragment - retainInstanceState recreates fragment on orientation change

When I use retainInstanceState(true) in fragment and use it with a FragmentPagerAdapter, the fragment is recreated. Which is not expected behaviour. What is a potential work around
I found a blog post which gives a solution not to use retainInstanceState which is not possible in my case
Turns out viewpager retains fragments and tries to find fragment with that id.
First thing to do in Fragment's onCreate:
setRetainInstance(true);
In activity with tabs, Make sure you handle onSaveInstanceState correctly
#Override
public void onSaveInstanceState(bundle){
super.onSaveInstanceState(bundle);
}
Even without saving viewpager id or reference to fragment as suggested in similar questions, the same fragment is reattached on orientation change

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.

Adding Fragment to BackStack using FragmentStatePagerAdapter

I have a FragmentStatePagerAdapter which is used as the ViewPagerAdapter for my ActionBar etc. I am trying to change a fragment and add the previous one to the backstack. It appears, however, that this is not possible.
If I look at the Code it seems as though the only way around this is to destroy the old Fragment then add the new one. This is not optimal for what I am trying to do (multipage form). What I really want to do is take the existing fragment and detach it, then add a new fragment and add it to the backstack.
I have tried this without the ViewPager and it works flawlessly. Short of rewriting my own FragmentStatePagerAdapter class that allows me to replace items in the Fragments List is there anything else I can do?

FragmentStatePagerAdapter doesn't call its fragments

I have FragmentStatePagerAdapter in a fragment with pager. Inside pager I have two fragments to switch between them. What is happening is that when I first come to fragment everything is done correctly, but when I go back and return there again then on the base fragment is called normally onCreate, onCreateView and so on, but on fragments in pager is not called anything, getItem on adapter is not called and pager view is blank. On all fragments I have setRetainInstance(true) which is needed due to a rotation behaviour handling.
Can you help me guys what to do with that?

Categories

Resources