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

Xamarin.Android WebView中window.print()无法正常工作的问题

解决Xamarin.Android WebView无法弹出新窗口执行打印的问题

核心问题原因

你已经开启了SetSupportMultipleWindows和JavaScriptCanOpenWindowsAutomatically,但没有在自定义的ExtendWebChromeClient中重写OnCreateWindow方法——Android WebView不会自动创建新窗口,必须通过这个回调手动处理window.open()的请求。

解决方案步骤

1. 完善ExtendWebChromeClient的实现

重写OnCreateWindow、OnCloseWindow等方法,处理新窗口的创建与销毁,同时确保新窗口的WebView配置正确:

public class ExtendWebChromeClient : WebChromeClient
{
    private Activity _context;
    private WebView _newWindowWebView;
    private Dialog _newWindowDialog;

    public ExtendWebChromeClient(Activity context)
    {
        _context = context;
    }

    // 处理window.open()请求,创建新窗口
    public override bool OnCreateWindow(WebView view, bool isDialog, bool isUserGesture, Message resultMsg)
    {
        // 创建新的WebView实例
        _newWindowWebView = new WebView(_context);
        WebSettings settings = _newWindowWebView.Settings;
        // 配置和主WebView一致的必要设置
        settings.JavaScriptEnabled = true;
        settings.DomStorageEnabled = true;
        settings.JavaScriptCanOpenWindowsAutomatically = true;
        settings.SetSupportZoom(true);
        settings.BuiltInZoomControls = true;
        settings.DefaultTextEncodingName = "utf-8";

        // 用Dialog承载新WebView,模拟新窗口
        _newWindowDialog = new Dialog(_context);
        _newWindowDialog.SetContentView(_newWindowWebView);
        _newWindowDialog.Window.SetLayout(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
        _newWindowDialog.Show();

        // 将新WebView的结果返回给系统,让JS能获取到newWindow对象
        WebView.WebViewTransport transport = (WebView.WebViewTransport)resultMsg.Obj;
        transport.WebView = _newWindowWebView;
        resultMsg.SendToTarget();

        // 监听新WebView的打印请求
        _newWindowWebView.SetWebChromeClient(new WebChromeClient());

        return true;
    }

    // 处理window.close()请求,关闭新窗口
    public override void OnCloseWindow(WebView window)
    {
        base.OnCloseWindow(window);
        _newWindowDialog?.Dismiss();
        _newWindowWebView?.Destroy();
    }
}

2. 清理主WebView的冗余配置

你代码中重复设置了SetWebViewClient(new WebViewClient())和SetWebViewClient(new HelloWebViewClient()),保留一个即可,避免覆盖配置。

3. 优化JS代码的可靠性

增加空值判断并适当延长超时时间,确保DOM渲染完成:

var newWindow = window.open();
if (!newWindow) {
    console.error("无法创建新窗口");
    return;
}
newWindow.document.body.innerHTML="<table>....</table>";
setTimeout(() => {
    newWindow.print();
    newWindow.close();
}, 1500);

4. 可选:跳过新窗口直接打印

如果不需要弹出新窗口,可直接在原WebView中生成打印内容,避免新窗口适配问题:

// 保存原页面内容
var originalContent = document.body.innerHTML;
// 替换为打印表格
document.body.innerHTML="<table>....</table>";
setTimeout(() => {
    window.print();
    // 打印完成后恢复原内容
    document.body.innerHTML = originalContent;
}, 1000);

验证方法

重新编译运行后,点击页面按钮:

  • 会弹出承载新WebView的Dialog窗口
  • 超时后触发系统打印界面
  • 打印完成后自动关闭Dialog

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:17:36