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

ViewPager2嵌套NestedScrollView中WebView加载多Twitter iframe时收缩异常

解决NestedScrollView+双WebView+ViewPager2布局中WebView收缩问题

针对你在ViewPager2的Fragment中使用NestedScrollView嵌套两个WebView(中间插入广告)时出现的WebView加载后收缩、内容显示不全(尤其含Twitter iframe时)的问题,可通过以下步骤解决:

1. 基础布局优化

调整NestedScrollView属性

确保NestedScrollView开启fillViewport,让内部内容能正确填充视口:

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <!-- 内部垂直布局:WebView1 + 广告容器 + WebView2 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <WebView
            android:id="@+id/web_view1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <LinearLayout
            android:id="@+id/ad_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp" />

        <WebView
            android:id="@+id/web_view2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</androidx.core.widget.NestedScrollView>

禁用WebView自身滚动

避免WebView的滚动逻辑和NestedScrollView的滚动冲突,同时防止WebView因自身滚动导致高度异常:

WebView webView1 = findViewById(R.id.web_view1);
WebView webView2 = findViewById(R.id.web_view2);

// 隐藏滚动条
webView1.setVerticalScrollBarEnabled(false);
webView1.setHorizontalScrollBarEnabled(false);
webView2.setVerticalScrollBarEnabled(false);
webView2.setHorizontalScrollBarEnabled(false);

// 禁用触摸滚动事件
webView1.setOnTouchListener((v, event) -> true);
webView2.setOnTouchListener((v, event) -> true);

2. 动态计算WebView高度(适配动态内容/iframe)

WebView的onPageFinished仅触发主文档加载完成,像Twitter iframe这类异步加载的内容不会触发该回调,因此需要通过JS监听内容高度变化:

启用JS并注入监听脚本

// 开启JavaScript支持
webView1.getSettings().setJavaScriptEnabled(true);
webView2.getSettings().setJavaScriptEnabled(true);

// 定义JS交互接口,用于接收内容高度更新通知
class WebViewHeightCallback {
    @JavascriptInterface
    public void onHeightChanged(int height) {
        requireActivity().runOnUiThread(() -> {
            // 更新当前WebView的高度
            if (webView1.isAttachedToWindow()) {
                ViewGroup.LayoutParams params = webView1.getLayoutParams();
                params.height = height;
                webView1.setLayoutParams(params);
            } else if (webView2.isAttachedToWindow()) {
                ViewGroup.LayoutParams params = webView2.getLayoutParams();
                params.height = height;
                webView2.setLayoutParams(params);
            }
        });
    }
}

// 给WebView绑定JS接口
webView1.addJavascriptInterface(new WebViewHeightCallback(), "HeightCallback");
webView2.addJavascriptInterface(new WebViewHeightCallback(), "HeightCallback");

// 注入监听脚本:监听主文档及所有iframe加载完成后的高度变化
String heightMonitorJs = "function updateHeight() { " +
        "   HeightCallback.onHeightChanged(document.body.scrollHeight); " +
        "} " +
        "window.onload = updateHeight; " +
        "var iframes = document.getElementsByTagName('iframe'); " +
        "for(var i=0; i<iframes.length; i++) { " +
        "   iframes[i].onload = updateHeight; " +
        "}";

// 在WebView加载完成后注入脚本
webView1.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        view.loadUrl("javascript:" + heightMonitorJs);
    }
});

webView2.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        view.loadUrl("javascript:" + heightMonitorJs);
    }
});

3. 优化ViewPager2页面切换时的布局重绘

ViewPager2默认预加载相邻页面,导致Fragment在后台时WebView高度计算异常,可在Fragment的onResume中重新触发高度计算:

@Override
public void onResume() {
    super.onResume();
    // 重新计算两个WebView的高度
    refreshWebViewHeight(webView1);
    refreshWebViewHeight(webView2);
}

private void refreshWebViewHeight(WebView webView) {
    if (webView != null && webView.getSettings().getJavaScriptEnabled()) {
        webView.evaluateJavascript("document.body.scrollHeight", heightStr -> {
            try {
                int height = Integer.parseInt(heightStr.replace("\"", ""));
                ViewGroup.LayoutParams params = webView.getLayoutParams();
                params.height = height;
                webView.setLayoutParams(params);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        });
    }
}

4. 特殊情况处理:Twitter iframe显示异常

如果仍存在Twitter iframe导致的高度问题,可尝试禁用WebView硬件加速(部分机型硬件加速会导致iframe布局异常):

webView1.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
webView2.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

内容的提问来源于stack exchange,提问作者Garvi Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:28:28