在ViewPager中滚动Webview

16

我在一个ViewPager中有一个WebView。问题是ViewPager似乎会消耗所有的水平滚动事件,这样我就无法在WebView中进行水平滚动(垂直方向可以)。

有什么办法可以让WebView优先消耗水平滚动事件吗?


你需要覆盖视图翻页器,我现在不在家,希望我回去后还能记得。 - Shereef Marzouk
嘿 :) 这里有些新东西,但我还是卡在同样的问题上了... :) - cV2
3个回答

9
不要问我为什么这段代码会被格式化成这样, 1. 实现一个自定义的 ViewPager 实例,如下所示:
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. 在您的主要(ViewPager)活动中,将以下行添加到视图分页器中

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. 最后,运行它 :=) 如果缩放级别在初始缩放级别,则允许更改页面,其他时间可以导航您的 Web 视图

附注: *不要忘记* 使用您刚创建的 CustomViewPager 类更改您 *.xml 文件中的 ViewPager 。

祝你好运 :)


2
是否可以更改代码,以便如果Web视图完全滚动到一侧,然后我在该方向上进一步滚动,即使WebView没有初始缩放级别,ViewPager也会消耗滚动? - anonymous
是的,我认为这可能是可行的,你只需要调整代码(对我来说不是必要的),但是如果你分享你的代码,对其他人来说可能会很棒。理论上只需访问webview的X、Y轴,并检查是否在边界上,如果是,则让viewpager更改页面:)祝你好运:=)(如果你喜欢,请投票支持我的回答) - cV2

1

试试这个

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");

0
晚来一步,我提出了一个不同的方法来解决这个问题,通过重写WebViewonTouchEvent方法。它适用于ViewPagerViewPager2。希望这能帮助未来的SO。
注意:将您的WebView替换为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)

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接