• 问题记录-CoordinatorLayout+WebView使用遇到的问题


    需求背景:

    使用CoordinatorLayout+viewpager+tablayout+webview实现首页折叠效果。

    使用问题:

    在使用过程中首页的页面为原生/h5混合页,在原生页面正常,嵌套h5页面头部CollapsingToolbarLayout无法滚动,开始的解决方式是在webview上面嵌套NestedScrollView。

    项目上线后发现了新的问题,h5关于滑动的js都无法执行。

    原因分析:

    引用Coordinator layout 和 WebView中的话是:

    如果将webview放在NestedScrollView中,height是wrap_contents,并且webview扩展为页面的大小。 因此无法垂直滚动。 滚动是在NestedScrollView而不是webview本身发生的。
    所以页面中没有js的结果会看到任何滚动事件,所以它不知道你已经滚动到页面的末尾加载更多的内容。 硬件层也由GL纹理支持,并且它们具有最大尺寸(这是最小的屏幕尺寸,尽管通常不会大得多)。 如果视图变得大于最大纹理大小,那么它将不能与硬件层一起使用。 这适用于任何视图,而不仅仅是webview。

    建议:

    不要将webview放在NestedScrollView中。 不要在wrap_contents模式下使用webview。 让webview滚动网页本身。

    解决方案:

    自定义webview,由它实现NestedScrollingChild。

    package com.ingtube.common.widget;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    
    import androidx.core.view.MotionEventCompat;
    import androidx.core.view.NestedScrollingChild;
    import androidx.core.view.NestedScrollingChildHelper;
    import androidx.core.view.ViewCompat;
    
    
    
    public class NestedScrollWebView extends ScrollWebView implements NestedScrollingChild {
        public NestedScrollWebView(@NotNull Context context) {
            super(context);
            init();
        }
    
        public NestedScrollWebView(@NotNull Context context, @NotNull AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public NestedScrollWebView(@NotNull Context context, @NotNull AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
        private int mLastMotionY;
    
        private final int[] mScrollOffset = new int[2];
        private final int[] mScrollConsumed = new int[2];
    
        private int mNestedYOffset;
    
        private NestedScrollingChildHelper mChildHelper;
    
    
        private void init() {
            mChildHelper = new NestedScrollingChildHelper(this);
            setNestedScrollingEnabled(true);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            boolean result = false;
    
            MotionEvent trackedEvent = MotionEvent.obtain(event);
    
            final int action = MotionEventCompat.getActionMasked(event);
    
            if (action == MotionEvent.ACTION_DOWN) {
                mNestedYOffset = 0;
            }
    
            int y = (int) event.getY();
    
            event.offsetLocation(0, mNestedYOffset);
    
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    mLastMotionY = y;
                    startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
                    result = super.onTouchEvent(event);
                    break;
                case MotionEvent.ACTION_MOVE:
                    int deltaY = mLastMotionY - y;
    
                    if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
                        deltaY -= mScrollConsumed[1];
                        trackedEvent.offsetLocation(0, mScrollOffset[1]);
                        mNestedYOffset += mScrollOffset[1];
                    }
    
                    int oldY = getScrollY();
                    mLastMotionY = y - mScrollOffset[1];
                    int newScrollY = Math.max(0, oldY + deltaY);
                    deltaY -= newScrollY - oldY;
                    if (dispatchNestedScroll(0, newScrollY - deltaY, 0, deltaY, mScrollOffset)) {
                        mLastMotionY -= mScrollOffset[1];
                        trackedEvent.offsetLocation(0, mScrollOffset[1]);
                        mNestedYOffset += mScrollOffset[1];
                    }
                    if(mScrollConsumed[1]==0 && mScrollOffset[1]==0) {
                        trackedEvent.recycle();
                        result = super.onTouchEvent(trackedEvent);
                    }
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    stopNestedScroll();
                    result = super.onTouchEvent(event);
                    break;
            }
            return result;
        }
    
        // NestedScrollingChild
    
        @Override
        public void setNestedScrollingEnabled(boolean enabled) {
            mChildHelper.setNestedScrollingEnabled(enabled);
        }
    
        @Override
        public boolean isNestedScrollingEnabled() {
            return mChildHelper.isNestedScrollingEnabled();
        }
    
        @Override
        public boolean startNestedScroll(int axes) {
            return mChildHelper.startNestedScroll(axes);
        }
    
        @Override
        public void stopNestedScroll() {
            mChildHelper.stopNestedScroll();
        }
    
        @Override
        public boolean hasNestedScrollingParent() {
            return mChildHelper.hasNestedScrollingParent();
        }
    
        @Override
        public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
            return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
        }
    
        @Override
        public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
            return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
        }
    
        @Override
        public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
            return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
        }
    
        @Override
        public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
            return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
        }
    
    
    }

    参考链接:

    解决coordinatorlayout嵌套webView遇到的问题

  • 相关阅读:
    leetcode 14. 最长公共前缀
    leetcode13. 罗马数字转整数
    leetcode 21.合并两个有序链表
    leetcode14-最长公共前缀
    leetcode13-罗马数字转整数
    leetcode11- 盛最多水的容器
    leetcode9-回文数
    leetcode7- 整数反转
    leetcode 1-两数之和
    文件的上传
  • 原文地址:https://www.cnblogs.com/fangg/p/13839976.html
Copyright © 2020-2023  润新知