不幸的是,您需要修改 source code of Xamarin.Forms.MasterDetailPage 以提供所需的行为。问题是当从MasterDetail中移除Detail页面时(从Webview切换到另一个页面),所有的原生控件都被释放了;即使您保留对 Xamarin.Forms.Webview 或 Xamarin.Forms.Page 对象的硬引用。
在源码中可以看到,如果_detail属性不为null,则从MasterDetailPage.PageController.InternalChildren中移除。您可能需要检查包含Xamarin.Forms.Webview 的Xamarin.Forms.Page,并确保它没有从页面控制器中删除。这将保留本机 webview 和 webview 处理程序,因此不会重新加载任何内容。需要注意的几点:
- 确保您也没有将您的 web 视图页面重新添加到 MasterDetail
PageController.InternalChildren
- webview 页面将保持加载到内存中。这很重要,因为如果您的网站执行大量 javascript、存储或更多内容,您应该注意,即使未显示它也会保留在内存中
您可以通过创建一个新的 Forms 项目并将App 类代码替换为以下代码来验证所有这些:
public class App : Application
{
public App()
{
MainPage = new MasterDetail();
}
}
public class MasterDetail : MasterDetailPage
{
static WebViewPage persistentWebPage = new WebViewPage();
public MasterDetail()
{
var masterPage = new MasterPage();
persistentWebPage = new WebViewPage();
Master = masterPage;
Detail = persistentWebPage;
masterPage.listview.ItemSelected += (sender, e) =>
{
var item = e.SelectedItem as string;
if (string.IsNullOrEmpty(item))
return;
switch (item)
{
case "1":
Detail = persistentWebPage;
break;
default:
Detail = new ContentPage { BackgroundColor = Color.Red };
break;
}
masterPage.listview.SelectedItem = null;
IsPresented = false;
};
}
}
public class MasterPage : ContentPage
{
public ListView listview = new ListView { ItemsSource = new string[] { "1", "2", "3" } };
public MasterPage()
{
Title = "Master";
Content = listview;
}
}
public class WebViewPage : ContentPage
{
public static WebView webView = new WebView { Source = "https://www.google.com/" };
public WebViewPage()
{
Content = webView;
}
}
接下来在 Android 项目中创建一个渲染器(iOS 也可以,我刚做了 Android)并复制以下代码:
public class WebViewRenderer_Droid : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
if (e.NewElement == null)
Console.WriteLine("*********e.NewElement is null");
else
Console.WriteLine("*********e.NewElement is not null");
if (e.OldElement == null)
Console.WriteLine("*********e.OldElement is null");
else
Console.WriteLine("*********e.OldElement is not null");
if (Control == null)
Console.WriteLine("*********Control is null");
else
Console.WriteLine("*********Control is not null");
base.OnElementChanged(e);
}
}
运行项目并从 web 视图页面切换回来。您会看到Control 和e.OldElement 在某一时刻都为空。这证明即使有硬引用,您的本地处理程序也会被处理。这是因为您无法控制 Xamarin.Forms 如何处理本机控件引用。 From the source code of Xamarin.Forms,我们可以看到,如果 Control 为空,那么一切都会重新创建。
我希望这会有所帮助!深入挖掘来解决这个问题很有趣。