Xamarin Forms WebView缓存问题:调用GoBack()未触发Navigating事件
嘿,我之前在做Xamarin.Forms浏览器项目的时候也碰到过一模一样的问题,刚好能给你几个实用的解决思路:
首先得说清楚原因:Xamarin.Forms早期版本(比如你用的2.5.x系列,对应VS2017 15.5.4)在Android平台上,调用GoBack()/GoForward()确实不会自动触发Navigating事件——这是因为原生Android WebView的goBack()方法本身不会抛出导航开始的事件,Forms层也没做额外的事件转发处理。
下面是三个可行的解决方案:
方案一:手动触发Navigating事件(快速临时解决)
在调用GoBack()之前,我们可以手动构造NavigatingEventArgs并触发事件,代码示例如下:
// 假设你的WebView控件名为MyWebView if (MyWebView.CanGoBack) { // 获取返回目标的URL var targetUrl = MyWebView.BackStack.Last().Url; // 构造导航事件参数 var navArgs = new WebNavigatingEventArgs( WebNavigationType.Back, new UrlWebViewSource { Url = targetUrl }, targetUrl); // 手动触发Navigating事件 MyWebView.Navigating?.Invoke(MyWebView, navArgs); // 执行返回操作 MyWebView.GoBack(); }
这个方法简单直接,适合快速解决当前问题,但缺点是需要在所有调用GoBack()的地方都加这段代码。
方案二:自定义WebViewRenderer(彻底解决)
如果希望所有导航操作(包括前进后退)都能自动触发Navigating事件,可以自定义Android平台的WebView渲染器,拦截原生WebView的导航开始事件并转发到Forms层:
- 先在共享项目中创建自定义WebView类:
public class CustomWebView : WebView { // 不需要额外属性,只是用来标记使用自定义渲染器 }
- 在Android项目中实现自定义渲染器:
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))] namespace YourAppNamespace.Droid.Renderers { public class CustomWebViewRenderer : WebViewRenderer { protected override void OnElementChanged(ElementChangedEventArgs<WebView> e) { base.OnElementChanged(e); if (Control != null && e.NewElement != null) { // 设置自定义WebViewClient来拦截导航事件 Control.SetWebViewClient(new CustomWebViewClient(e.NewElement as CustomWebView)); } } } public class CustomWebViewClient : Android.Webkit.WebViewClient { private readonly CustomWebView _formsWebView; public CustomWebViewClient(CustomWebView formsWebView) { _formsWebView = formsWebView; } public override void OnPageStarted(Android.Webkit.WebView view, string url, Android.Graphics.Bitmap favicon) { base.OnPageStarted(view, url, favicon); // 无论哪种导航方式(点击链接/前进后退),都触发Forms层的Navigating事件 var navArgs = new WebNavigatingEventArgs( WebNavigationType.Other, new UrlWebViewSource { Url = url }, url); _formsWebView.Navigating?.Invoke(_formsWebView, navArgs); } } }
- 最后在XAML中替换原来的
WebView为CustomWebView即可:
<local:CustomWebView x:Name="MyWebView" Navigating="MyWebView_Navigating" Navigated="MyWebView_Navigated" />
方案三:升级Xamarin.Forms版本(长远解决)
你当前使用的VS2017 15.5.4对应的Xamarin.Forms版本比较老旧,后续的Xamarin.Forms 3.x及以上版本已经修复了这个问题——调用GoBack()/GoForward()会自动触发Navigating事件。如果项目允许的话,可以尝试升级Xamarin.Forms NuGet包到稳定的新版本。
不过要注意:升级可能会带来一些兼容性问题(比如旧版API弃用),建议先在测试环境验证后再应用到正式项目中。
另外补充一句:其实调用GoBack()后Navigated事件是正常触发的,如果你的业务逻辑只需要在导航完成后处理,也可以暂时利用这个事件过渡。
内容的提问来源于stack exchange,提问作者maradev21

