The root cause is the implementation of #onInterceptTouchEvent. An older implementation of SlidingPaneLayout made a call to #canScroll, which would check if the touch target could scroll, and if so, would scroll the touch target instead of sliding the panel. The most recent implementation looks like it always intercepts the motion event, once the drag threshold exceeds the slop, except in the case where the X drag exceeds the slop and the Y drag exceeds the X drag (as noted by the OP).
One solution to this is to copy SlidingPaneLayout and make a few changes to get this to work. Those changes are:
Modify the ACTION_MOVE case in #onInterceptTouchEvent to also check #canScroll,
if (adx > slop && ady > adx || canScroll(this, false, Math.round(x - mInitialMotionX), Math.round(x), Math.round(y))) { ... }
Modify the final check in #canScroll to special case ViewPager. This modification could also be done in a subclass by overriding #canScroll, since it doesn't access any private state.
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { ... /* special case ViewPagers, which don't properly implement the scrolling interface */ return checkV && (ViewCompat.canScrollHorizontally(v, -dx) || ((v instanceof ViewPager) && canViewPagerScrollHorizontally((ViewPager) v, -dx))) } boolean canViewPagerScrollHorizontally(ViewPager p, int dx) { return !(dx < 0 && p.getCurrentItem() <= 0 || 0 < dx && p.getAdapter().getCount() - 1 <= p.getCurrentItem()); }
There is likely a more elegant way to do this by fixing the ViewDragHelper, but this is something Google should address in a future update of the support package. The hacks above should get the layout working with ViewPagers (and other horizontally scrolling containers?) now.