I have a ViewPager on the root-level of an activity.
Each page of the pager contains a ListFragment (backed by a FragmentPagerAdapter).
Some of the list view items should contain additionally ViewPagers to support swiping the content of those items (e. g. a horizontal gallery inside a list item).
How can I nest view pagers? ViewPager -> ListView (in a page) -> ViewPager (inside a list item)
I can swipe between the ListFragments horizontally and I can swipe the whole list vertically, but I cannot swipe inside list items.
I added an OnTouchListener
to the interior ViewPager
:
private OnTouchListener mSuppressInterceptListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(
event.getAction() == MotionEvent.ACTION_DOWN &&
v instanceof ViewGroup
) {
((ViewGroup) v).requestDisallowInterceptTouchEvent(true);
}
return false;
}
};
This just detects ACTION_DOWN touch events on the inner ViewPager
and prevents the outer one from intercepting it. Because it returns false, only the ACTION_DOWN event should be hit; all the other events will be ignored. You can add this listener to every element you want to "protect" from the outer ViewPager
's scrolling, though obviously if you want to pick up any other touch behaviour on those elements you'll need to deal with them inside the touch listener and possibly implement a better listener.
Credit to @Rodja who gave me the idea in the first place.
While it's not the best interaction design, it is possible to implement this by overwriting the dispatchTouchEvent(MotionEvent ev) method of the root-level Activity and using requestDisallowInterceptTouchEvent(true) on the mainPager and the current ListView to prevent other scrolling. Look at this example:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Fragment listFragment = getSupportFragmentManager().findFragmentByTag(
"android:switcher:" + R.id.pager + ":" + (mainPager.getCurrentItem()));
mainPager.getChildAt(mainPager.getCurrentItem());
if (listFragment == null)
return super.dispatchTouchEvent(ev);
ViewPager embeddedPager = (ViewPager) listFragment.getView().findViewById(R.id.videopager);
if (embeddedPager != null) {
int[] position = new int[2];
embeddedPager.getLocationOnScreen(position);
if (ev.getY() > position[1] && ev.getY() < position[1] + embeddedPager.getHeight()) {
mainPager.requestDisallowInterceptTouchEvent(true);
if (embeddedPager.getScrollX() % embeddedPager.getWidth() != 0) {
ListView listView = (ListView) listFragment.getView().findViewById(
android.R.id.list);
listView.requestDisallowInterceptTouchEvent(true);
}
}
}
return super.dispatchTouchEvent(ev);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With