WAI
Status Update
Comments
az...@gmail.com <az...@gmail.com> #2
I'm having the same problem.
ch...@google.com <ch...@google.com>
ad...@android.com <ad...@android.com> #3
This happens when using a FragmentPagerAdapter, as it will call setUserVisibleHint before committing a transaction to add new fragments. This behavior dates back to very early versions of FragmentPagerAdapter.
This is working as intended; the user visible hint was always meant to be settable from outside of the lifecycle. There was previously a bug where calling setUserVisibleHint before a fragment was created but after it was added to a transaction would cause the fragment to enter the created state before the transaction was committed. FragmentPagerAdapter reliably triggered this case. The fragment would be in the STARTED state after an override of setUserVisibleHint called super.setUserVisibleHint.
The user visible hint is optional and defaults to true. You can set it to false and the FragmentManager will do things like defer the onStart phase and later until other fragments in the manager have finished running their loaders, etc. This helps for cases like ViewPager where you want to prioritize the visible page, not the offscreen pages.
If FragmentPagerAdapter were to commit the transaction first and run the fragment up through onStart as a result before setting the visibility hint, we will have already kicked off the work we intended to defer. The hint has to be able to set before the lifecycle methods run since it can affect timing of those lifecycle methods. Therefore, custom fragment code must be prepared to receive calls to setUserVisibleHint before the fragment's onCreate occurs.
This is working as intended; the user visible hint was always meant to be settable from outside of the lifecycle. There was previously a bug where calling setUserVisibleHint before a fragment was created but after it was added to a transaction would cause the fragment to enter the created state before the transaction was committed. FragmentPagerAdapter reliably triggered this case. The fragment would be in the STARTED state after an override of setUserVisibleHint called super.setUserVisibleHint.
The user visible hint is optional and defaults to true. You can set it to false and the FragmentManager will do things like defer the onStart phase and later until other fragments in the manager have finished running their loaders, etc. This helps for cases like ViewPager where you want to prioritize the visible page, not the offscreen pages.
If FragmentPagerAdapter were to commit the transaction first and run the fragment up through onStart as a result before setting the visibility hint, we will have already kicked off the work we intended to defer. The hint has to be able to set before the lifecycle methods run since it can affect timing of those lifecycle methods. Therefore, custom fragment code must be prepared to receive calls to setUserVisibleHint before the fragment's onCreate occurs.
to...@gmail.com <to...@gmail.com> #4
Well the thing is that is was then broken since as long as I remember to until version 24.
Should be documented now, as I'm sure a lot of people do rely on previous "bugged" behavior and not new "correct" one.
Before all fragment received setUserVisibleHint(false) before on create.
Then the visible loaded fragment the setUserVisibleHint(true) after onCreate.
Should be documented now, as I'm sure a lot of people do rely on previous "bugged" behavior and not new "correct" one.
Before all fragment received setUserVisibleHint(false) before on create.
Then the visible loaded fragment the setUserVisibleHint(true) after onCreate.
ad...@android.com <ad...@android.com> #5
We can make this explicit in the docs for setUserVisibleHint.
to...@gmail.com <to...@gmail.com> #6
Thanks. A line in changelog could help too.
ad...@android.com <ad...@android.com> #7
Agreed.
ad...@android.com <ad...@android.com> #8
Would you find it useful if we added an API onUserVisibleHintChanged with guarantees that it would only be called if the fragment was at least in the CREATED state?
to...@gmail.com <to...@gmail.com> #9
Well for my use case it would not if it does not covers layout inflated and attached.
But maybe other could find that useful.
Previous behavior was simple to manage activity transitions to viewpagers fragments and other tricks without having to deal with viewpager listeners and interfaces.
If documented and getUserVisibleHint() is set to true before onCreate in all cases (even with other adapters) then workarounds are not so hard to implement too.
But maybe other could find that useful.
Previous behavior was simple to manage activity transitions to viewpagers fragments and other tricks without having to deal with viewpager listeners and interfaces.
If documented and getUserVisibleHint() is set to true before onCreate in all cases (even with other adapters) then workarounds are not so hard to implement too.
ad...@android.com <ad...@android.com> #10
Sounds good. Docs changes are coming.
[Deleted User] <[Deleted User]> #11
"Would you find it useful if we added an API onUserVisibleHintChanged with guarantees that it would only be called if the fragment was at least in the CREATED state?"
Yes, this would be very helpful. Before 24.0.0, I never had any issues with it being called before onCreate.
Yes, this would be very helpful. Before 24.0.0, I never had any issues with it being called before onCreate.
[Deleted User] <[Deleted User]> #12
Yeah, that would super nice of you guys! I inject some dependencies during the onCreate stage and it looks like now I have started getting NPEs because of that change. Having a method that works similarly, but is called after onCreate would be very helpful!
wi...@gmail.com <wi...@gmail.com> #13
My codes is broken after updating to 24.0.0
I need to send data(eg: page view) for analytic purpose whenever a fragment is visible to user. I am following suggestion from this posthttp://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager
Before sending analytics, I retrieve data in Fragment onCreate using getArguments().getString(title)
and then override method
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
sendAnalyticPageView(title); // this title value is obtained during onCreate
}
}
This code is broken because now the setUserVisibleHint no longer called after onCreate method.
Maybe this is not proper way to do..
Perhaps the Fragment could have a method such as onFragmentVisible() or onUserVisibleHintChanged suggested by #11 fa...@dolly.com
for us to do something when the fragment is visible to user.
Is there better way for me to send analytic data when fragment is visible to user?
As you see a lot of people been asking same question in stackverflow but no proper answer yet.
Would be nice if sending analytics is taking part in considerations when designing the module.
Now I roll back to 23.3.0 for temporary fix...
I need to send data(eg: page view) for analytic purpose whenever a fragment is visible to user. I am following suggestion from this post
Before sending analytics, I retrieve data in Fragment onCreate using getArguments().getString(title)
and then override method
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
sendAnalyticPageView(title); // this title value is obtained during onCreate
}
}
This code is broken because now the setUserVisibleHint no longer called after onCreate method.
Maybe this is not proper way to do..
Perhaps the Fragment could have a method such as onFragmentVisible() or onUserVisibleHintChanged suggested by #11 fa...@dolly.com
for us to do something when the fragment is visible to user.
Is there better way for me to send analytic data when fragment is visible to user?
As you see a lot of people been asking same question in stackverflow but no proper answer yet.
Would be nice if sending analytics is taking part in considerations when designing the module.
Now I roll back to 23.3.0 for temporary fix...
az...@gmail.com <az...@gmail.com> #14
You cant set your 'title' variable in the newInstance method. Set it to a Fragment's variable.
wi...@gmail.com <wi...@gmail.com> #15
#14 AzureusSme without using newInstance, 'title' would be null if Fragment recreate.
az...@gmail.com <az...@gmail.com> #16
onSaveInstanceState() ?
le...@gmail.com <le...@gmail.com> #17
[Comment deleted]
le...@gmail.com <le...@gmail.com> #18
"Would you find it useful if we added an API onUserVisibleHintChanged with guarantees that it would only be called if the fragment was at least in the CREATED state?"
Yes, this would be very helpful. Will this be added in a future release?
Yes, this would be very helpful. Will this be added in a future release?
wi...@gmail.com <wi...@gmail.com> #19
#16 AzureusSme
onRestoreInstanceState() only happen after onCreate, the setUserVisibleHint happen before onCreate. So in ends up i cant get my value in setUserVisibleHint.
If set value in Fragment's variable solve the problem then introduction of Fragment newInstance would be useless.
onRestoreInstanceState() only happen after onCreate, the setUserVisibleHint happen before onCreate. So in ends up i cant get my value in setUserVisibleHint.
If set value in Fragment's variable solve the problem then introduction of Fragment newInstance would be useless.
wo...@gmail.com <wo...@gmail.com> #20
I'm not 100% sure but I think this means that onCreate will be called with a nonnull bundle for the initial onCreate. This just broke my app as usually a null for the savedState means that the fragment is created for the first time.
pa...@gmail.com <pa...@gmail.com> #21
#10
with this task being closed, please dont forget about creating new api. onUserVisibleHintChanged would be big help for people who need to trigger events after fragments are in created state.
with this task being closed, please dont forget about creating new api. onUserVisibleHintChanged would be big help for people who need to trigger events after fragments are in created state.
bu...@gmail.com <bu...@gmail.com> #22
"You can set it to false and the FragmentManager will do things like defer the onStart phase and later until other fragments in the manager have finished running their loaders, etc. This helps for cases like ViewPager where you want to prioritize the visible page, not the offscreen pages."
how do you do this? i tried instance the fragment then setting uservisiblehint to false before returning it in the viewpager, but I'm way off I think...
how do you do this? i tried instance the fragment then setting uservisiblehint to false before returning it in the viewpager, but I'm way off I think...
Description
Version used: 24.0.0
Theme used: Irrelevant
Devices/Android versions reproduced on: Irrelevant
Before 24.0.0 when using support fragments with or without viewPager, setUserVisibleHint would be called with the parameter set to true only after onCreate and onAttach called.
Since 24.0.0 this is no more the case and it's called before.
Telling a fragment that it's visible to the user when it's not even created sounds like a big bug as there's no more easy way to detect that the fragment is loaded and visible and trigger some refresh.