Lifecycle of Fragment that holds a ViewPager - android

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().

Related

call next fragment's lifecycle method when use viewpager2 with TabLayoutMediator

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.

onPause(), onStop(), setUserVisibleHint(), and onHiddenChange() is not getting Called while using ViewPager Fragments

I have a ViewPager which contain 2 tabs(2 Separate fragments).
My Second Tab consist of further 6 child tabs (each separate fragment) in another ViewPager.
Now When i switch between 6 child tabs, setUserVisibleHint() method is called.
But when i am present on my any of 6 child tabs(i.e fragment) and i try to switch between the 2 parent tabs. None of the methods like onPause(), onStop(), setUserVisibleHint(), and onHiddenChange() of child tab fragment do not get called.
So can you please help me to know which method will get called of child fragment when i switch between 2 parent tabs?
And if no methods will get called of child fragments, then how can i achieve or know that there is switch between parent tabs and call a method in child fragments?
You shouldn't rely on a fragment lifecycle in this case. It's controlled by adapter and if any of those callbacks gets called it doesn't guarantee you anything.
Use onPageChangeListener instead. You can set it on a ViewPager object via addOnPageChangeListener in onResume for example, and call removeOnPageChangeListener in onPause. It has a method onPageChanged which will be called every time you switch the page.

Where should I code in Fragment that it will run only once- android

I am implementing Tab Layout with Swipeable Views in android. For implementation I had followed
AndroidHive
and
Tabs and swipe views.
But with both, I am facing the same problem. I am having 3 fragments but when my application run, onCreateView of 1st and 2nd Fragment called instead of only of 1st fragment's. When I swipe and go to 2nd fragment, onCreateView of 3rd Fragments get called.
So, whatever I code in 2nd fragment execute in the first fragment view. I researched and came to know that it happen to keep the next fragment into memory for smooth animation. But I am wondering, where I would code in the fragment so that it will execute only once or how to restrict Fragment getItem() method to be called only once. What can be the solution for this?
According to the Fragment's documentation you can implement the onCreate() link:
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
This should fix your problem, because i guess you now only use the onCreateView which might be called more than once.
For more information you can check the Fragment's lifecycle or documentation

difference between fragmentTransaction.add and fragmentTransaction.replace

What I already known is:
after fragmentTransaction.replace(), current fragment's onStop() function will be called
while fragmentTransaction.add() won't.
and after calling fragMgr.popBackStack();, we will return to previous fragment no matter fragmentTransaction.replace or fragmentTransaction.add() is used
So what does fragmentTransaction.replace do?
I can understand we can "add" a fragment opon a previous fragment and later return to previous fragment by popBackStack(), BUT:
if previous fragment is "replaced" by current fragment, I guess previous fragment is removed and current fragment is added in, how can it return to previous fragment when popBackStack() called?
You can add multiple fragments to a container and they will be layered one on top of the other. If your fragments have transparent backgrounds you will see this effect and will be able to interact with the multiple fragments at the same time.
This is what will happen if you use FragmentTransaction.add on a container. Your added fragment will be placed on top of your existing fragment.
If you use FragmentTransaction.replace(R.id.container,fragment) it will remove any fragments that are already in the container and add your new one to the same container.
You can also use the add method without a container id and your fragment will simply be added to the list of fragments in the FragmentManager and you can recall these at any time by their Tag value.
You can still return to a previous configuration IF you added the transaction to back stack. You can do this even if a previous operation removed a fragment. The removed fragment is remembered in the transaction and popping the back stack brings it back.
Two choices
Let's say you have a fragment container.
And, your task is to add a fragment into the container.
You can do this by calling any of the following methods
1) add(containerId,fragment)
2) replace(containerId,fragment)
But both methods differ in behavior !!!
Although both methods will add your fragment into the fragment container, their innards(internal working) differ based on the two possible states of the fragment container.
When fragment container
1) does not have any fragment in it.
2) already have one or multiple fragments attached to it.
Let's see what happens when we call add() and replace() method.
Case 1: When there is no fragment attached in a container
In this case, both methods will add the fragment to the container. So they will produce same effect.
Case 2: When the fragmentContainer already has fragment/fragments
add(): adds the new fragment on the top another fragment
replace(): removes everything then adds the new fragment
Example
So suppose the Fragment container has fragments[A->B->C].
Now you want to add a new fragment D.
add() method result will be [A->B->C->D]
replace() method result will be [D]
Relevant Link:
Check this Demo project for better understanding.

Fragment LIfecycle in Custom Tab View

I have a custom widget that performs FragmentTransaction.replace when buttons are pressed. Currently, my code is set up such that the first time a fragment is created, it attaches a bunch of stuff to the view that isn't originally part of the xml layout file.
When the app first launches, all my fragments show stuff correctly, however, let's say I start on Fragment A. I can then transition to Fragment B (with B showing up correctly), however, when I transition back to Fragment A, all the stuff I have attached to the view of Fragment A is now gone. I know this happens because onCreateView is called which probably means the Fragment's view is re-generated when FragmentTransaction.replace is called.
Is there a way where I can keep my fragments around instead of having them re-generate their views when FragmentTransaction.replace is called?
Thanks!
Instead of using fragmentTransaction.replace, use fragmentTransaction.show and fragmentTransaction.hide.
That will keep your fragments from being destroyed.

Categories

Resources