Determine when a ViewPager changes pages
Use the ViewPager.onPageChangeListener
:
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
// Check if this is the page you want.
}
});
Differentiating between user scroll and programatic page change in ViewPager
OK, so it turns out that I was right about the answer lying in ViewPager.onPageChangeListener
. In particular it lies in using onPageScrollStateChanged(int state)
. Essentially there are three states that a page in a ViewPager
can be in:
- Dragging: Indicates that the pager is currently being dragged by the user.
- Idle: Indicates that the pager is in an idle, settled state.
- Settling: Indicates that the pager is in the process of settling to a final position.
So the dragging state only occurs when the current page is being physically dragged by the user. Thus when the user has swiped a page the states occur in the following order: Dragging -> Settling -> Idle. Now, the onPageSelected(int position)
method is called between the "Settling" and "Idle" states. Thus, in order to determine whether or not a page change was caused by a user scroll one just needs to check that the previous state was "dragging" and that the current state is "Settling". You can then keep a boolean
variable to track whether or not the page change was user initiated or not and check it in your onPageSelected(int position)
method.
Here is my onPageScrollStateChanged
method
public void onPageScrollStateChanged(int state)
{
if (previousState == ViewPager.SCROLL_STATE_DRAGGING
&& state == ViewPager.SCROLL_STATE_SETTLING)
userScrollChange = true;
else if (previousState == ViewPager.SCROLL_STATE_SETTLING
&& state == ViewPager.SCROLL_STATE_IDLE)
userScrollChange = false;
previousState = state;
}
The if
and else if
statements need not be so explicit but I did so for clarity.
Is there a way to check whether ViewPager is currently scrolling between pages?
The solution I found allows me to identify whether there is a scroll in progress. scrollState has three values defined in ViewPager: SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING and SCROLL_STATE_SETTLING. Now I can check scrollState in the onTouch method and act accordingly.
@Override
public void onPageScrollStateChanged(int state) {
scrollState=state;
}
Detect ViewPager tab change inside Fragment
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
}
}
}
How to determine when Fragment becomes visible in ViewPager
How to determine when Fragment becomes visible in ViewPager
You can do the following by overriding setUserVisibleHint
in your Fragment
:
public class MyFragment extends Fragment {
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
}
else {
}
}
}
Related Topics
How to to Check If a User Has Rated Your App on the Google Play
Android - Running a Method Periodically Using Postdelayed() Call
How to Monitor Sim State Change
Android, How to Create Option Menu
Android Manifest Restrict to Tablets
Android - How to Get Application Name? (Not Package Name)
Android Studio: Creating Landscape Layouts
Editing Functionality of Host Card Emulation in Android
Android: Volley Http Request Custom Header
Java.Lang.Noclassdeffounderror: Android.Support.V7.Appcompat.R$Styleable
Why the View Keeps Flashing When Using Jetpack Navigation with Compose