I have got a weird issue with the 3 tabs of my ActionBar :
When i go from my second tab to the third, onCreateView() is not called, i like it because values in my third tab are in the same state.
Now, i will switch to the first tab and go back to the third, and now onCreateView() is called, and i don't want that...
Someone knows how to avoid this ? I don't understand why there is a difference between my second and my first tab !
Thank you for reading
It's probably because of the offscreenlimit in viewpager (I suppose it's your case).
It's set by default to one which means that view pager holds one fragment at each side of your currently visible tab in memory. (And when it's in memory it means that onCreateView() gets not called)
Related
I am making an application that has MainActivity that contains BottomNavigationView and FrameLayout above it. There are 3 Fragments say Fragment A, B, and C.
My doubt is, How do I make switching of Fragments as quick as YouTube Android application? By saying quick, I mean that, when I am on "Home" tab of Youtube application and I switch to the "Trending" tab and again go back to the "Home" tab, it simply loads "Home" tab within fraction of seconds, as if it just hided the inflated page in background and showed up when selected from BottomNavigationView. And also, It inflates the page exactly to the same position where I left.
When I am trying to implement the same in my Application, the RecyclerView in Fragment A re-inflates if I come back from Fragment B.
I am expecting the idea how they do it and in which method they do it (For eg. onStart or onDestroy or onViewCreated)...
If you are using viewpager then Increase the viewpager offset limit
viewpager.OffscreenPageLimit = 2;
Tt's limit is one by default. I hope this may fix your issue.
Thanks
Without me pasting any code, i have an activity that shows three fragments using a viewpager to swipe between them.
When the activity is created, tab one is showing.. If i select the second tab and go back to the first tab, everything is fine. But if i select the third tab and then select the first tab again, the onResume method is called within the first tab and its causing some undesirable results... why would onResume only be called when coming from the third tab and not the second? Its like tab one is being killed when you swipe to tab three, but tab one is not being killed if you just swipe to tab two..
Without seeing the code I can only guess, but when you use tab you are going to be using a FragmentPagerAdapter or FragmentPagerStateAdapter this keeps reference to the fragments that are kept alive. I'm going to guess that you are using the FragmentPagerStateAdapter which only keeps certain fragments alive and destroys other fragments when they leave the view. So that when you are on the 3rd fragment, the first fragment is being destroyed, which is recreated and thus calls onResume when you go back and visit it. When you are on the 2nd tab, the fragment isn't destroyed and so when you visit it, it does not need to call onResume. Fragments keep one fragment to the left and one to the right "alive" even though they are not in view. So when you are on 1, 2 is alive. When you are on 2, 1 & 3 are alive, when you are on 3, 2 is alive. I hope this helps.
To add more to BlackHat's answer,
You should use FragmentStatePagerAdapter, if you dont already, instead of FragmentPagerAdapter.
Also you should set the OffscreenPageLimit property of yoru view pager to the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state.
I am trying to implement swipe views with 2 tabs. For that, I am using view pager with 2 fragments. Now, the problem is that as soon as the main activity is opened (that contains those two tabs), onCreateView function is called for both the fragments. Please help me as how can I avoid calling of onCreateView of second fragment when one is in use.
Thanks,
Arpit
ViewPager retains the fragment to the left and to the right of the current view by default. This is to reduce a choppy user experience - that way you can begin swiping left or right and immediately see what is there without delay.
It is possible to disable (or increase the number of fragments to be retained) with setOffscreenPageLimit(0), but seriously consider if this is the right approach.
I have an scrollable tabs + swipe activity with 3 different fragments on it. It works well but I don't want my fragments to be destroyed when I navigate between them. For example, when I create the activity, it's shown the first fragment but it's created the second one too. When I swipe to the second fragment, the third is created, so I can swipe to the third one and it will be created before I open it. When I return to the second one, my third fragment still stays created but when I return to the first one, the third fragment is deleted.
There would be any way to avoid this? I don't want my fragments to be deleted when I navigate between them.
If you use a ViewPager, it has a method called setOffscreenPageLimit(int limit). Try and see if setting that higher works
This answer should help you figure out what's going on. Pretty much you are most likely using a FragmentStatePagerAdapter, when you should be using a FragmentPagerAdapter. That keeps it from deleting fragments not in view.
If, for performance reasons, you need to have the fragments deleted when they aren't being used, there are other options. Either look at why the performance is that bad when you have only 3 tabs (It shouldn't be unless you are doing something wrong with a listview, or have a map open, etc.) or you can code the fragments to save their state when they are being destroyed (which should be happening anyways with a FragmentStatePagerAdapter).
If that doesn't help, we'll need more info on what you are doing exactly to help.
I have an application using two tabs, both containing fragments. I am using the FragmentPagerAdapter to manage tab changes. All works fine with two tabs.
I recently added a third tab and am having a bit of trouble. tab1(fragment1) is a LinearLayout of small fragments. tab2(fragment2) is a simple layout of text. tab3(fragment3) is also a simple layout of text.
If I switch between tab1 and tab2 both work properly and retain their states. However, if I switch between tab1 and tab3, tab3 shows the text properly but tab1 shows a blank tab.
I know that if a tab goes more than 1 position off the current position the fragment will be destroyed and the fragment will need to be recreated. Does FragmentPagerAdapter not do this automatically?
I discovered that if I rotate the device (with tab1 selected), the tab1 fragment will be restored with its correct state so the fragment is not being destroyed. It seems like there is an issue with the layout not being correctly recreated by the ViewPager but this is only a guess.
As a work around I set myViewPager.setOffscreenPageLimit(2) and the layout is retained. I would like to get this to work as I think its supposed to without forcing the fragments to stay in memory.
Reading docs for setOffScreenPageLimit(), makes me think your approach is fine. Look at this:
If you have a small number of pages (3-4) that you can keep active all
at once, less time will be spent in layout for newly created view
subtrees as the user pages back and forth.
You should keep this limit low, especially if your pages have complex
layouts.
I'm curious though if setRetainInstance(true) will work, since it's the Adapter who decides to recreate a fragment not that it's get recreated during some Android change config operation.
Add
setRetainInstance(true);
in onCreateView method of a Fragment