65

I have a ViewPager with multiple fragments. In one Fragment I play audio. When I swipe to another fragment I want to stop the audio playback. How do I detect that the another fragment is now visible in the ViewPager?

I've tried overriding onStop and onHiddenChanged. No success. There must be some "you're not active anymore" method to override. No?

galvan
  • 7,400
  • 7
  • 38
  • 55
l33t
  • 18,692
  • 16
  • 103
  • 180

1 Answers1

140

I did some digging and it turns out that ViewPager will call both: setUserVisibleHint and setMenuVisibility. I would override setUserVisibleHint since the documentation for setUserVisibleHint states:

Set a hint to the system about whether this fragment's UI is currently visible to the user. This hint defaults to true and is persistent across fragment instance state save and restore. An app may set this to false to indicate that the fragment's UI is scrolled out of visibility or is otherwise not directly visible to the user. This may be used by the system to prioritize operations such as fragment lifecycle updates or loader ordering behavior.

Try putting this code in your fragment:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    // Make sure that we are currently visible
    if (this.isVisible()) {
        // If we are becoming invisible, then...
        if (!isVisibleToUser) {
            Log.d("MyFragment", "Not visible anymore.  Stopping audio.");
            // TODO stop audio playback
        }
    }
}
louielouie
  • 14,881
  • 3
  • 26
  • 31
  • 3
    setUserVisibleHint was never called in my case. – Wayne Jun 19 '12 at 16:42
  • 1
    Wayne: In my experience, I've found that setUserVisibleHint is called if ViewPager's adapter is a FragmentPagerAdapter, but not if it is a FragmentStatePagerAdapter. So if you're having issues, try to make sure you're using FragmentPagerAdapter. – louielouie Sep 17 '12 at 16:29
  • 5
    Yichuan Wang: To use Fragment's setUserVisibleHint in lower API levels, use the Android Support Library http://developer.android.com/tools/extras/support-library.html For example, http://developer.android.com/reference/android/support/v4/app/Fragment.html#setUserVisibleHint(boolean) is available for API level 4. – louielouie Sep 17 '12 at 16:30
  • 2
    Works great but this is not called again after orientation change. Therefore the hint is not restored but the fragment is. How can I achieve a recall? – Louis Nov 25 '12 at 12:13
  • Same for me: this isn't called after calling (and finishing it) a new activity from the fragment, so not valid for me – noloman Jan 08 '13 at 14:49
  • You need to handle `onResume` and `onOrientationChanged` too. – l33t Jan 14 '13 at 15:16
  • And you can use getUserVisibleHint() in your onOrientationCahnged method. – Thomas Decaux Jun 10 '14 at 14:16
  • didn't work. Still gets called when I select a neighbor, and claims it's visible (as it technically is, as you can start to drag and see part of it.) – StarWind0 May 11 '15 at 22:47
  • 3
    This is not reliable, it get called automatically sometimes. I found a better alternative http://stackoverflow.com/a/25822814/1979347 – Rohan Kandwal Jul 06 '15 at 12:45