Xamarin.Forms 5.0.0.2196版WebView加载Google Viewer预览PDF链接失效如何解决?
问题根因
该问题是Xamarin.Forms 5.0.0.2196版本对WebView的默认配置做了调整,同时谷歌文档查看器的内部链接都基于iframe内跳转,默认不会被外层WebView的导航事件捕获导致的。
修复方案
需要分平台自定义WebView渲染器拦截内部跳转请求,手动触发导航事件:
Android端
- 自定义WebView渲染器,开启谷歌文档必备的JavaScript、DomStorage权限,重写
ShouldOverrideUrlLoading方法拦截所有跳转
示例代码:
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))] namespace YourAppNamespace.Droid.Renderers { public class CustomWebViewRenderer : WebViewRenderer { public CustomWebViewRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) { base.OnElementChanged(e); if (Control != null) { Control.Settings.JavaScriptEnabled = true; Control.Settings.DomStorageEnabled = true; Control.SetWebViewClient(new CustomWebViewClient(Element)); } } } internal class CustomWebViewClient : WebViewClient { private readonly Xamarin.Forms.WebView _formsWebView; public CustomWebViewClient(Xamarin.Forms.WebView webView) { _formsWebView = webView; } public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request) { var navArgs = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = request.Url.ToString() }, request.Url.ToString()); _formsWebView.SendNavigating(navArgs); if (navArgs.Cancel) return true; view.LoadUrl(request.Url.ToString()); return true; } } }
iOS端
- 自定义WebView渲染器,重写
DecidePolicy方法拦截iframe跳转,手动触发Navigating事件
示例代码:
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))] namespace YourAppNamespace.iOS.Renderers { public class CustomWebViewRenderer : WkWebViewRenderer { protected override void OnElementChanged(VisualElementChangedEventArgs e) { base.OnElementChanged(e); if (e.NewElement != null) { NavigationDelegate = new CustomNavigationDelegate(Element as Xamarin.Forms.WebView); } } } internal class CustomNavigationDelegate : WKNavigationDelegate { private readonly Xamarin.Forms.WebView _formsWebView; public CustomNavigationDelegate(Xamarin.Forms.WebView webView) { _formsWebView = webView; } public override void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler) { var navArgs = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = navigationAction.Request.Url.ToString() }, navigationAction.Request.Url.ToString()); _formsWebView.SendNavigating(navArgs); decisionHandler(navArgs.Cancel ? WKNavigationActionPolicy.Cancel : WKNavigationActionPolicy.Allow); } } }
注意事项
- 如果需要处理新窗口打开的链接,iOS端可额外配置
UIDelegate拦截新窗口请求,在当前WebView加载或者跳转外部浏览器 - 不要在Forms层重复给WebView的Source赋值,避免重复加载导致事件丢失
- 拦截到下载类链接时可直接调用原生下载接口处理,无需走WebView加载
内容的提问来源于stack exchange,提问作者tuha
相关产品推荐
相关产品推荐

