問題記錄-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遇到的問題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM