Reserve the loaded contents of the WebView page when switching from the current page in the Master / Detail layout in Xamarin Forms

I use the layout Master / Detailto create a navigation menu and multiple pages. One of the pages is a control WebView, and nothing more. When I switch from this WebView page from the navigation menu and then switch back, the contents of the WebView disappear, the state also disappears. This happens both on iOSand on Android.

But if I go from a WebView page to a completely different page (a page without a wizard / part), returning to the WebView page, everything will be fine. All contents and status are saved.

I need to reload the page, but user operations will be lost. Is there a way to save page content and state and restore them without reloading the page?

+4
source share
5 answers

I found a working solution, although it looks more like a hack. This is instead of going to a subpage in Master / Detail when I touch a menu item, I go to another page, which means a level below 1. When the user returns from this page, everything will be saved. But in this way the navigation menu will no longer be. But it normal.

0
source

, Xamarin.Forms.MasterDetailPage, . , Detail MasterDetail ( Webview ) ; Xamarin.Forms.Webview Xamarin.Forms.Page.

, _detail null, MasterDetailPage.PageController.InternalChildren. Xamarin.Forms.Page, Xamarin.Forms.Webview, , . webview webview, . :

  • , - MasterDetail PageController.InternalChildren
  • - . , , 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);
    }
}

- . , Control e.OldElement . , . , , Xamarin.Forms . Xamarin.Forms, , Control NULL, .

, ! , .

+4

UIViewController , UIViewController, , .

, WebViewController WebViewController.

WebView :

private static ViewController vc;

public static WebViewController SharedInstance()
{
    if (vc == null)
    {
        var storyboard = UIStoryboard.FromName("MainStoryboard", null);
        vc = storyboard.InstantiateViewController("WevViewController") as WevViewController;
    }

    return vc;
}

, -,

public void DisplayWebview()
{
    WevViewController webvw = WevViewController.SharedInstance();
    NavigationController.PushViewController(webvw,true);
}
0

App static ContentPage, WebView. ContentPage App , -, .

using Xamarin.Forms;

namespace PersistWebViewSample
{
    public class StartPage : ContentPage
    {
        public StartPage()
        {
            var navigateToWebViewButton = new Button
            {
                Text = "Open Persistent Web View"
            };
            navigateToWebViewButton.Clicked += async (sender, e) => await Navigation.PushAsync(App.PersistentWebView);

            Title = "Start";

            Content = navigateToWebViewButton;
        }
    }

    public class App : Application
    {
        static readonly string xamarinUrl = "https://www.xamarin.com/";

        public App()
        {

            MainPage = new NavigationPage(new StartPage());
        }

        public static ContentPage PersistentWebView { get; } = new ContentPage
        {
            Title = "Persistent Web View",
            Content = new WebView
            {
                Source = xamarinUrl
            }
        };
    }
}

enter image description here

0

To fix this, I created a custom web view view renderer. When I create a new web view in the renderer (for example, the new WKWebView (Frame, opts)), I replace it with a subclass of WKWebview, which overrides Dispose, causing it to do nothing. Check out the original webview in OnElementChanged as you wish.

0
source

Source: https://habr.com/ru/post/1665380/


All Articles