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

如何在Xamarin.Android(Android)中根据动态HTML自动调整WebView高度

问题根因

Android 原生 WebView 嵌套进 ScrollView 时,wrap_content 属性存在固有兼容缺陷,同时你之前的实现存在四个核心问题:

  1. WebView 初始状态设为 GONE,该状态下系统不会执行内容测量逻辑,导致高度计算结果异常
  2. 在 OnPageFinished 中调用 Thread.Sleep 阻塞了 UI 线程,WebView 渲染流程被暂停,拿到的高度是未渲染完成的错误值
  3. 没有做 CSS 像素到 Android 物理像素的单位转换,直接使用 JS 返回值设置高度会出现尺寸偏差
  4. JS 执行返回的数值自带双引号,直接转换为 Int 会失败,导致高度设置不生效

解决方案

优先采用自定义 WebView 的兜底方案,不需要依赖 JS 计算,稳定性最高;如果不想自定义控件,可以用修改后的 JS 计算方案。

方案1:自定义自适应高度 WebView(最稳定)

直接重写 WebView 的测量逻辑,无需额外的 JS 计算,自动适配内容高度:

  1. 新建自定义 WebView 类
public class AutoHeightWebView : Android.Webkit.WebView
{
    public AutoHeightWebView(Context context) : base(context) { }

    public AutoHeightWebView(Context context, IAttributeSet attrs) : base(context, attrs) { }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // 将高度测量模式改为AtMost,自动适配内容高度
        int heightSpec = MeasureSpec.MakeMeasureSpec(int.MaxValue >> 2, MeasureSpecMode.AtMost);
        base.OnMeasure(widthMeasureSpec, heightSpec);
    }
}
  1. 修改 XML 布局中的 WebView 控件,替换为自定义类即可,原有其他布局结构不需要改动,TextView 可保留。

方案2:修正原有 JS 计算逻辑

如果不想自定义控件,可以按照以下步骤修改原有代码:

  1. 修改 WebView 初始化配置
var webView = FindViewById<Android.Webkit.WebView>(Resource.Id.webViewExtra);
// 初始状态设为INVISIBLE,保证系统会执行测量逻辑
webView.Visibility = ViewStates.Invisible;
webView.Settings.JavaScriptEnabled = true;
webView.Settings.UseWideViewPort = true;
webView.Settings.LoadWithOverviewMode = true;
// 关闭WebView自身滚动,滚动交给外层ScrollView
webView.VerticalScrollBarEnabled = false;
webView.HorizontalScrollBarEnabled = false;
  1. 修改 OnPageFinished 逻辑
public override void OnPageFinished(WebView webView, string url)
{
    base.OnPageFinished(webView, url);
    // 不要阻塞UI线程,用PostDelayed给渲染预留时间
    webView.PostDelayed(() => {
        webView.EvaluateJavascript(@"(function() {
            return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
        })();", new WebViewValueCallback(webView));
    }, 200);
}
  1. 修改高度设置逻辑,处理单位转换和返回值格式
public class WebViewValueCallback : Object, IValueCallback
{
    private readonly WebView _webView;
    public WebViewValueCallback(WebView webView)
    {
        _webView = webView;
    }

    public void OnReceiveValue(Object value)
    {
        if (value == null) return;
        // 去掉JS返回值自带的双引号
        string heightStr = value.ToString().Trim('"');
        if (int.TryParse(heightStr, out int cssHeight))
        {
            // CSS像素转Android物理像素,乘以设备密度
            float density = _webView.Context.Resources.DisplayMetrics.Density;
            int actualHeight = (int)(cssHeight * density);
            
            ViewGroup.LayoutParams layoutParams = _webView.LayoutParameters;
            layoutParams.Height = actualHeight;
            _webView.LayoutParameters = layoutParams;
            // 高度设置完成后再显示WebView
            _webView.Visibility = ViewStates.Visible;
        }
    }
}

内容的提问来源于stack exchange,提问作者Federico Navarrete

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 10:36:03