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?
Related
I have this structure
Tabs with fragments
---(one)Fragment with ViewPager2
------- Fragments inside ViewPager2
When I change between ViewPager's fragments, onResume and onPause are called just fine.
Problem comes when I click on another tab to load another fragment. When I do that for some reason the fragment that hosts the ViewPager will receive onHiddenChanged callback but its children will not receive any callback.
I've tried all 3 constructors for FragmentStateAdapter, none of them helped and I have no idea how I will notify viewpager's fragments for such a lifecycle change. Any ideas?
I use Viewpager2 With setup tablayout using TabLayoutMediator but the issue is
when I swipe viewpager first fragment to the second fragment here only call
current fragment's lifecycle methods, but when I click on tablayout
then call next fragment's lifecycle methods. I don't know why this happens?
This happens because the method that TabLayoutMediator uses to move to the selected fragment causes the RecyclerView to cache the next Fragment as it uses Smooth Scrolling.
This should not be a problem UNLESS you are doing something in the wrong part of the Fragment's lifecycle. If you only want do something when a Fragment is displayed then only do it in the Fragments onResume method as the behaviour you describe will only take the cached Fragment to "Started" state.
I have something that has me stumped. I have a Fragment (Fragment A) that has ViewPager that contains three fragments (for swiping left/right). So, if within another fragment, in the onBackPressed() method, I do a getFragmentManager().popBackStack() call, Fragment A will be again be visible (with the ViewPager of sub-fragments) which is the desired state. However, there is no method with Fragment A or within the ViewPager that indicates that Fragment A/ViewPager is again visible.
None of the fragment methods referenced in the Fragment lifecycle (http://developer.android.com/guide/components/fragments.html) that should be called when "The fragment returns the layout from the back stack" or any of the methods called within OnPageChangeListener (yes, I do call viewPager.setOnPageChangeListener(this) within Fragment A's onCreateView).
Thoughts on where I could look?
I have an app with a ViewPager that is added to the layout, then later replaced by another fragment, with the change added to the transaction back stack. I have Log statements in each of the lifecycle methods of the pager. When the Back button is pressed and the pager is returned to the layout, my logcat output shows these methods called for the pager: onCreateView(), onActivityCreated(), onStart(), onResume(). Note that when a fragment goes into the back stack, its view is destroyed, but the fragment object is not destroyed, so when the fragment returns from the back stack, there is no call to onCreate().
This behavior is consistent with the lifecycle diagram in the Fragment Guide. You should be able to use the call to onResume() as an indication that your pager is visible. I can only suggest that you add debug output to the lifecycle methods for your pager and look at the output. If you think its wrong, please add it to the post of your question. Also indicate what fragment transaction method(s) you are using. If by chance you are using hide() instead of remove() or replace(), then the lifecycle events are different and you may need to use onHiddenChanged().
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.
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