XF 5.0.0.2244 CarouselPage滑到第三页后返回首页WebView被销毁重建问题
问题根因
Xamarin.Forms 5.x版本安卓端CarouselPage默认离屏页面缓存数为1,仅保留当前页相邻的1个页面实例。滑动到第3个子页面时,第1个页面超出缓存范围被系统回收,返回时会重新初始化Page1,导致WebView重新加载。iOS端CarouselPage默认缓存所有子页面,因此无此问题。
解决方案
方案1:调整离屏页面缓存数(推荐,实现成本最低)
直接通过Xamarin.Forms提供的安卓平台专属API,修改CarouselPage的缓存数量,缓存所有子页面即可避免回收。
修改App.cs中的代码如下:
using Xamarin.Forms.PlatformConfiguration; using Xamarin.Forms.PlatformConfiguration.AndroidSpecific; CarouselPage carouselPage = new CarouselPage(); // 安卓端设置离屏缓存数为2,可覆盖所有3个子页面,参数可根据实际子页面总数调整为「总页数-1」 carouselPage.On<Android>().SetOffscreenPageLimit(2); carouselPage.Children.Add(new Page1()); // webViewPage carouselPage.Children.Add(new Page2()); carouselPage.Children.Add(new Page3());
该方案适用于子页面数量较少(5个以内)的场景,无明显内存占用增加。
方案2:手动保存恢复WebView状态(适合子页面数量多、不想全量缓存的场景)
如果子页面数量较多,全量缓存会占用过多内存,可以在Page1的生命周期方法中手动保存、恢复WebView的状态,步骤如下:
- 给Page1.xaml中的WebView添加Name属性方便后台引用:
<WebView x:Name="webView" Source="www.stackoverflow.com" MinimumHeightRequest="300"/>
- 在Page1.xaml.cs中添加状态保存、恢复逻辑:
private double _savedScrollY; private string _savedUrl; protected override void OnDisappearing() { base.OnDisappearing(); if (Device.RuntimePlatform == Device.Android) { // 保存当前页面地址 _savedUrl = webView.Source.ToString(); // 保存滚动位置 webView.EvaluateJavaScript("window.scrollY", (res) => { if (double.TryParse(res?.ToString(), out double scrollY)) { _savedScrollY = scrollY; } }); } } protected override void OnAppearing() { base.OnAppearing(); if (Device.RuntimePlatform == Device.Android && !string.IsNullOrEmpty(_savedUrl)) { // 恢复到上次访问的地址 webView.Source = _savedUrl; // 页面加载完成后恢复滚动位置 webView.Navigated += (s, e) => { webView.EvaluateJavaScript($"window.scrollTo(0, {_savedScrollY})", null); }; } }
如果需要保留表单输入等更复杂的状态,可搭配WebView自定义渲染器调用安卓原生WebView的SaveState、RestoreState方法实现。
内容的提问来源于stack exchange,提问作者Erdogan
相关产品推荐
相关产品推荐

