So, I ended up developing a solution by disallowing propagation of touch events to the ViewPager and scrolling pages when the overScrollBy event of the WebView is triggered. You can determine the direction you want to scroll in by checking the deltaX of the event. Here's a kotlin solution:
override fun overScrollBy(deltaX: Int, deltaY: Int, scrollX: Int, scrollY: Int, scrollRangeX: Int, scrollRangeY: Int, maxOverScrollX: Int, maxOverScrollY: Int, isTouchEvent: Boolean): Boolean {
if(parent.parent is WebViewPager) {
val viewPager: WebViewPager = (parent.parent as WebViewPager)
if(viewPager.scrollState == ViewPager.SCROLL_STATE_IDLE) {
if(deltaX > 0) {
if(checkAdapterLimits(1, viewPager.currentItem)) //right
(parent.parent as ViewPager).setCurrentItem(viewPager.currentItem + 1,true)
}
else {
if(checkAdapterLimits(-1, viewPager.currentItem)) //left
(parent.parent as ViewPager).setCurrentItem(viewPager.currentItem - 1,true)
}
}
}
return false
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
parent.requestDisallowInterceptTouchEvent(true)
return super.onInterceptTouchEvent(event)
}
private fun checkAdapterLimits(direction: Int, position: Int) : Boolean {
return if(direction < 0) //left
position >= 1
else //right
position < (parent.parent as ViewPager).adapter.count - 1
}
Edited, in order to stop scrolling to just one page at a time, you need to check the scroll state of the ViewPager to make sure it's idle.
You'll need to add a property to your custom ViewPager and toggle it with an OnPageChangedListener on the ViewPager instance you're using.
ViewPager:
class WebViewPager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {
var scrollState: Int = SCROLL_STATE_IDLE
fun setDurationScroll(millis: Int) {
try {
val viewpager = ViewPager::class.java
val scroller = viewpager.getDeclaredField("mScroller")
scroller.isAccessible = true
scroller.set(this, OwnScroller(context, millis))
} catch (e: Exception) {
e.printStackTrace()
}
}
inner class OwnScroller(context: Context, durationScroll: Int) : Scroller(context, DecelerateInterpolator()) {
private var durationScrollMillis = 1
init {
this.durationScrollMillis = durationScroll
}
override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) {
super.startScroll(startX, startY, dx, dy, durationScrollMillis)
}
}
}
OnPageChangedListener:
viewPager!!.setDurationScroll(300)
viewPager!!.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
viewPager.scrollState = state
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
}
})