make ViewPager.setVisibility(GONE) trigger onPause to onDestroyView callbacks - android

I'd like to show and hide ViewPager on particular occassions, however this ViewPager element holds quite a bit of Bitmaps that should be recycled. When I do setVisibility(GONE) on VierPager it doesn't trigger any of the callbacks related to its' pages.
Is there any system way to tell ViewPager to destroy view of all the pages it hosts ? I think I could wright somewhat like:
foreach(page from viewPagerPages) {
page.onPause();
page.onStop();
page.onDestroyView();
}
but I'm not sure about it.
Thanks.

To destroy Views use ViewPager's method removeAllViews (). It is inherited from ViewGroup.
removeAllViews () - Call this method to remove all child views from the ViewGroup.
Here a lot of different methods to manipulate ViewPager.

Related

FragmentPagerAdapter setPrimaryItem called multiple times

Structure:
CoordinatorLayout -> AppBarLayout + ViewPager
Scroll RecyclerView or other touch gestures throw setPrimaryItem in ViewPager. Called from ViewPager.onMeasure. Its normal behavior?
(support libs 25.1.0)
Trace:
ViewPager calls setPrimaryItem() in it's populate method.
ViewPager.populate()
The populate method in turn is called in a couple of cases, but the really important one (at least for figuring out these multiple calls) is the onMeasure() invocation.
ViewPager.onMeasure()
Look at like 851. Anything that causes the view hierarchy to remeasure is going to lead to your Adapter getting it's primary item calls set again.

ViewPager child view method callin automatic?

I implemented View Pager with fragment child A/B/C. To get selection of default Fragment(say A) I use mViewPager.setCurrentItem(position) and it work fine. But on this Second Fragment (B) view methods onViewCreated and setUserVisibleHint calling automatically.
Is there any way to prevent this !
You can try invoking ViewPager.setOffscreenPageLimit(0), which will no longer pre-load non-visible Fragments. The default value for the off-screen page limit is 1, so that should be the reason why the onViewCreated() and setUserVisibleHint() methods are being called for your other fragments.

Android: ViewPager, intercept on fragment load

I have a ViewPager which usually preloads some of its elements.
The user can interact with one page which should affects a part of all other elements of the ViewPager.
Currently all my logic is in onCreateView(). I need to get a handle when element is actually shown and change the common part.
I tried with onResume() but this function is called earlier. I don't want to redraw the whole element because this is not effective.
I am not sure but try using this method:
viewPager.setOffscreenPageLimit(0);
This method will call only one fragment at a time, while you are on that fragment.
Or
Another way is that you can get position of view pager's fragment at run time which is front of screen and according to that particular fragment position you can simply call your method by checking position Like: if(position == 1){}.

Programmatically removing a ViewPager, when are (or how can I ensure) contained Fragments are destroyed?

Having searched regarding this issue beforehand, I can find many discussions regarding dynamically adding and removing selected Fragments from a ViewPager. What I'm actually concerned about here however is how I can programmatically remove an entire ViewPager 'cleanly' from its containing ViewGroup, when that ViewPager has been used to display Fragments via a FragmentPagerAdapter, and ensure that the contained Fragments are destroyed properly.
To expand on the question a bit more, I have a landscape two-pane layout where a selection is made from a list within a Fragment on the left-hand-side, and chosen content is then placed on the right within a FrameLayout. The key thing is that the content may or may not be paginated. Therefore, the content must either be displayed in a ViewPager format, or if it is not paginated then it shall be represented by a single Fragment directly.
To show a single Fragment, I simply perform a FragmentTransaction as you normally would in order to place the Fragment into the FrameLayout container. If on the other hand it's paginated content to be shown, then instead I create a ViewPager and add it as a child of the FrameLayout.
When I need to change the content, then if the previous content was a stand-alone Fragment then I can simply remove it via FragmentTransaction .remove(). When I do this, the Fragment goes through the onPause() ... onDestroy() cycle as expected. If the previous content was a ViewPager then I remove it from the FrameLayout using .removeAllViews(). Here I come to the problem: I don't see any of the onPause() ... onDestroy() methods being called in any of the Fragments that were held within that ViewPager via the FragmentPagerAdapter.
From a user point of view, the application works fine. After several rounds of ViewPager being removed, I can see the GC reclaiming memory. However, I don't like the fact that those Fragments' end of life methods aren't called as I can't do any cleanup within them, and it just doesn't seem 'right'.
Is there a method I can hook into in order to remove the ViewPager's Fragments when the ViewPager is detached from its parent, perhaps? In other words, when I know that the ViewGroup is no longer in used, I would perform FragmentTransactions somewhere (perhaps in the FragmentPagerAdapter) to remove those Fragments.
Alternatively, I realise that I could just keep the ViewPager on the right permanently, and dynamically swap the Fragments within it. Of course it simply would not matter that at certain times it would only hold one page. If this would be a better way to go then I shall refactor my code to do this, but I would appreciate opinions.
However, I don't like the fact that those Fragments' end of life methods aren't called as I can't do any cleanup within them, and it just doesn't seem 'right'.
They should get cleaned up when the activity is destroyed, if that is not too late for you (e.g., heap issues).
In other words, when I know that the ViewGroup is no longer in used, I would perform FragmentTransactions somewhere (perhaps in the FragmentPagerAdapter) to remove those Fragments.
You did not execute the transactions to put the fragments there. Hence, you cannot readily execute the transactions to remove the fragments. If you switch to FragmentStatePagerAdapter, and call setAdapter(null), it should cause all existing fragments in the pager to be destroyed, by my reading of the source code. FragmentPagerAdapter never uses remove(), but FragmentStatePagerAdapter does, from its destroyItem() method, and all extant fragments are destroyed via destroyItem() when a new adapter (or null) is supplied to setAdapter().

Android Fragment onCreateView vs. onActivityCreated

I know that a fragment's view hierarchy has to be inflated in onCreateView, but what other functionality can be in onCreateView vs. what should wait for onActivityCreated? My current implementation uses separate activities for everything, and a typical activity does most of its work in its onCreate method, including inflating the view, setting the content view, initializing the various widgets with data, setting up listeners, etc.
So can this probably all be moved into onCreateView, or should some functions be put into an onActivityCreated method instead?
If your view is static, then moving any code to the onActivityCreated method is not necessary. But when you - for instance, fill some lists from the adapter, then you should do it in the onActivityCreated method as well as restoring the view state when setRetainInstance used to do so.
Also accessing the view hierarchy of the parent activity must be done in the onActivityCreated, not sooner.
onActivityCreated() is deprecated in fragment 1.3.0-alpha02 and there is a recommendation to use onViewCreated() instead. View is already created here and you can set listeners, observe LiveData from ViewModel, initialize recyclerView, etc.
For a better understanding, you can take a look at my blog post, where I describe the Android Fragment lifecycle in 137 seconds.

Categories

Resources