You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android NestedScrollView内嵌WebView回滑后内容无法滚动修复

问题根因

该滑动失效问题由三个配置错误共同导致:

  • WebView设置了android:isScrollContainer="false",直接禁用了自身的滚动响应能力,所有触摸事件默认全部上交父容器
  • WebView错误配置了仅适用于CoordinatorLayout直接子View的layout_behavior、layout_scrollFlags属性,干扰了嵌套滑动的事件分发逻辑
  • NestedScrollView与下方RecyclerView平级放置,两个可滚动容器争抢事件焦点,滑动经过RecyclerView区域再返回WebView位置时,事件分发链路断裂,WebView无法接收到滚动事件。
修复方案

按以下步骤调整即可解决:

  1. 调整布局层级与属性
    • 将原本和NestedScrollView平级的RecyclerView移入NestedScrollView内部,作为垂直布局的子项,同时给RecyclerView设置android:nestedScrollingEnabled="false",禁用自身滚动,统一由外层NestedScrollView调度滚动事件
    • 移除WebView上多余的layout_behavior、layout_scrollFlags属性,这类属性仅对CoordinatorLayout的直接子View生效
    • 将WebView的android:isScrollContainer改为true,高度从match_parent改为wrap_content,恢复自身滚动能力
    • 给最外层NestedScrollView保留app:layout_behavior="@string/appbar_scrolling_view_behavior"配置(如果用了CollapsingToolbarLayout的话),开启android:nestedScrollingEnabled="true"
  2. 补充WebView触摸事件配置
    • 给WebView设置触摸监听,按下时请求父容器暂时不要拦截事件,优先响应WebView内部滚动,抬起/取消时恢复父容器拦截能力
    • 开启WebView垂直滚动条,明确自身滚动边界
修正后代码

布局代码

<androidx.core.widget.NestedScrollView
    android:id="@+id/webScrollContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:nestedScrollingEnabled="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:visibility="@{playerType == PlayerViewType.WEB ? View.VISIBLE : View.GONE}"
    tools:visibility="gone">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <WebView
            android:id="@+id/previewWebView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:isScrollContainer="true" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/bottomListRv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:nestedScrollingEnabled="false"/>

    </LinearLayout>

</androidx.core.widget.NestedScrollView>

WebView初始化代码

@SuppressLint("SetJavaScriptEnabled", "JavascriptInterface")
private fun initWebView() {
    web.let {
        with(it.settings) {
            javaScriptEnabled = true
            userAgentString =
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.117 Safari/537.36"
            domStorageEnabled = true
            loadWithOverviewMode = true
            useWideViewPort = true
            mediaPlaybackRequiresUserGesture = true
            allowFileAccess = true
            cacheMode = WebSettings.LOAD_DEFAULT
        }
        // 开启垂直滚动条
        it.isVerticalScrollBarEnabled = true
        it.isHorizontalScrollBarEnabled = false

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            it.setLayerType(View.LAYER_TYPE_HARDWARE, null)
        }
        it.webChromeClient = WebChromeProgressClient()
        it.webViewClient = WebClient()

        // 触摸时优先响应WebView内部滚动
        it.setOnTouchListener { v, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> v.parent.requestDisallowInterceptTouchEvent(true)
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> v.parent.requestDisallowInterceptTouchEvent(false)
            }
            false
        }
    }
}

注意:如果WebView加载的是超长H5页面,wrap_content高度会导致WebView一次性渲染全部内容,触发内存占用过高问题,这种场景可以自定义实现支持嵌套滑动的WebView,重写onMeasure方法限制最大高度,配合NestedScrollView滑动逻辑实现分批渲染即可。

内容的提问来源于stack exchange,提问作者Viacheslav Kolisnichenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:09:18