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
相关产品推荐
相关产品推荐

