Reputation: 1161
I have a WebView
in a ViewPager
.
And the ViewPager
seems to consume all the horizontal scrolling, so that I can't scroll in the WebView
(vertical works).
How can I achieve that the WebView
has got priority consuming the horizontal scrolling?
Upvotes: 16
Views: 12264
Reputation: 5319
don't ask me why this code gets formatted like this,
1. implement a custom ViewPager Instance like this:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
public class CustomViewPager extends ViewPager {
private MagazineWebView_WithoutFlipWebView mCurrentPageWebView_; //custom webview
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (Constants.LOGGING) {
Log.v(Constants.LOG_OEAMTC_APP, "CustomViewPager - onInterceptTouchEvent");
}
// if view zoomed out (view starts at 33.12... scale level) ... allow
// zoom within webview, otherwise disallow (allow viewpager to change
// view)
if (mCurrentPageWebView_ != null && (mCurrentPageWebView_.getScale() * 100) > 34) {
Log.v(Constants.LOG_OEAMTC_APP, "CustomViewPager - intrcepted: " + String.valueOf((mCurrentPageWebView_.getScale() * > 100)));
this.requestDisallowInterceptTouchEvent(true);
}
else {
if (mCurrentPageWebView_ != null) {
Log.v(Constants.LOG_OEAMTC_APP,
"CustomViewPager - not intrcepted: " + String.valueOf(mCurrentPageWebView_.getScale() * 100));
}
this.requestDisallowInterceptTouchEvent(false);
}
return super.onInterceptTouchEvent(event);
}
public MagazineWebView_WithoutFlipWebView getCurrentPageWebView() {
return mCurrentPageWebView_;
}
public void setCurrentPageWebView(MagazineWebView_WithoutFlipWebView currentPageWebView) {
mCurrentPageWebView_ = currentPageWebView;
}
}
2. in your main (ViewPager) Activity add the following lines to the view pager
mViewPager_ = new AwesomePagerAdapter();
viewpapgerInLayout = (CustomViewPager) findViewById(R.id.awesomepager);
viewpapgerInLayout.setAdapter(mViewPager_);
viewpapgerInLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
viewpapgerInLayout.setCurrentPageWebView(mLstPagesWebviews_.get(position));
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
3. finally, run it :=) if the zoom level is at initial zoom, changes pages is allowed, all the other time you can navigate your web view
Ps.: Don't forget to change your ViewPager in your *.xml file with the CustomViewPager Class you just created
good luck :)
Upvotes: 9
Reputation: 3928
Late to this question and I come up with a different approach to fix this issue by override
the WebView
onTouchEvent
method. It works on both ViewPager
and ViewPager2
. Hope this would help the future SO.
Note: Replace your WebView
with NestedScrollWebView
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.webkit.WebView
import androidx.core.view.NestedScrollingChild
import androidx.core.view.NestedScrollingChildHelper
import androidx.core.view.ViewCompat
class NestedScrollWebView : WebView, NestedScrollingChild {
companion object {
val TAG: String = NestedScrollWebView::class.java.simpleName
}
private var lastMotionX: Int = 0
private var lastMotionY: Int = 0
private val scrollOffset = IntArray(2)
private val scrollConsumed = IntArray(2)
private var nestedOffsetY: Int = 0
private var childHelper = NestedScrollingChildHelper(this)
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
private fun init() {
isNestedScrollingEnabled = true
}
override fun onTouchEvent(event: MotionEvent): Boolean {
var result = false
val trackedEvent = MotionEvent.obtain(event)
val action = event.actionMasked
if (action == MotionEvent.ACTION_DOWN) {
nestedOffsetY = 0
}
val x = event.x.toInt()
val y = event.y.toInt()
event.offsetLocation(0f, nestedOffsetY.toFloat())
when (action) {
MotionEvent.ACTION_DOWN -> {
lastMotionX = x
lastMotionY = y
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
result = super.onTouchEvent(event)
}
MotionEvent.ACTION_MOVE -> {
var deltaY = lastMotionY - y
if (kotlin.math.abs(deltaY) > kotlin.math.abs(lastMotionX - x) &&
(canScrollVertically(1) || canScrollVertically(-1))
) {
requestDisallowInterceptTouchEvent(true)
}
if (dispatchNestedPreScroll(0, deltaY, scrollConsumed, scrollOffset)) {
deltaY -= scrollConsumed[1]
trackedEvent.offsetLocation(0f, scrollOffset[1].toFloat())
nestedOffsetY += scrollOffset[1]
}
lastMotionY = y - scrollOffset[1]
val oldY = scrollY
val newScrollY = Math.max(0, oldY + deltaY)
val dyConsumed = newScrollY - oldY
val dyUnconsumed = deltaY - dyConsumed
if (dispatchNestedScroll(0, dyConsumed, 0, dyUnconsumed, scrollOffset)) {
lastMotionY -= scrollOffset[1]
trackedEvent.offsetLocation(0f, scrollOffset[1].toFloat())
nestedOffsetY += scrollOffset[1]
}
result = super.onTouchEvent(trackedEvent)
trackedEvent.recycle()
}
MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
stopNestedScroll()
requestDisallowInterceptTouchEvent(false)
result = super.onTouchEvent(event)
}
}
return result
}
// NestedScrollingChild
override fun setNestedScrollingEnabled(enabled: Boolean) {
childHelper.isNestedScrollingEnabled = enabled
}
override fun stopNestedScroll() {
childHelper.stopNestedScroll()
}
override fun isNestedScrollingEnabled() =
childHelper.isNestedScrollingEnabled
override fun startNestedScroll(axes: Int) =
childHelper.startNestedScroll(axes)
override fun hasNestedScrollingParent() =
childHelper.hasNestedScrollingParent()
override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?) =
childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow)
override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?) =
childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)
override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean) =
childHelper.dispatchNestedFling(velocityX, velocityY, consumed)
override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float) =
childHelper.dispatchNestedPreFling(velocityX, velocityY)
}
Upvotes: 2
Reputation: 5033
Try this
WebView mWebView = (WebView) findViewById(R.id.MyWebview);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.getSettings().setUserAgentString("Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3");
Upvotes: 1