How create static WebView?

MindRusMindRus Member ✭✭
edited November 2018 in Xamarin.Forms

Hi, everyone!
I want to create static WebView, which i can use on diffrent pages.
I created public static ExtWebView staticWebView but its dont help me, my webview loading again.
I have Renderer:

[assembly: ExportRenderer(typeof(ExtWebView), typeof(ExtWebViewRenderer))]
namespace DirectorixRoom.Droid
{
public class ExtWebViewRenderer : ViewRenderer<ExtWebView, AWebView>, IWebViewDelegate
{
bool _ignoreSourceChanges;
ExtFormsWebChromeClient _webChromeClient;
IWebViewController ElementController => Element;

    public ExtWebViewRenderer(Context context) : base(context)
    {
        AutoPackage = false;
    }

    [Obsolete("This constructor is obsolete as of version 2.5. Please use WebViewRenderer(Context) instead.")]
    public ExtWebViewRenderer()
    {
        AutoPackage = false;
    }

    public void LoadHtml(string html, string baseUrl)
    {
        Control.LoadDataWithBaseURL(baseUrl ?? "file:///android_asset/", html, "text/html", "UTF-8", null);
    }

    public void LoadUrl(string url)
    {
        Control.LoadUrl(url);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (Element != null)
            {
                if (Control != null)
                    Control.StopLoading();
                ElementController.EvalRequested -= OnEvalRequested;
                ElementController.GoBackRequested -= OnGoBackRequested;
                ElementController.GoForwardRequested -= OnGoForwardRequested;

                _webChromeClient?.Dispose();
            }
        }

        base.Dispose(disposing);
    }

    protected virtual ExtFormsWebChromeClient GetFormsWebChromeClient()
    {
        return new ExtFormsWebChromeClient();
    }

    protected override Size MinimumSize()
    {
        return new Size(Context.ToPixels(40), Context.ToPixels(40));
    }

    protected override AWebView CreateNativeControl()
    {
        return new AWebView(Context);
    }

    protected override void OnElementChanged(ElementChangedEventArgs<ExtWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            var webView = CreateNativeControl();
            webView.LayoutParameters = new global::Android.Widget.AbsoluteLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent, 0, 0);
            webView.SetWebViewClient(new WebClient(this));

            _webChromeClient = GetFormsWebChromeClient();
            _webChromeClient.SetContext(Context as Activity);
            webView.SetWebChromeClient(_webChromeClient);

            webView.Settings.JavaScriptEnabled = true;
            webView.Settings.DomStorageEnabled = true;
            webView.Settings.AllowFileAccessFromFileURLs = true;
            SetNativeControl(webView);
        }

        if (e.OldElement != null)
        {
            var oldElementController = e.OldElement as IWebViewController;
            oldElementController.EvalRequested -= OnEvalRequested;
            oldElementController.EvaluateJavaScriptRequested -= OnEvaluateJavaScriptRequested;
            oldElementController.GoBackRequested -= OnGoBackRequested;
            oldElementController.GoForwardRequested -= OnGoForwardRequested;

            Control.RemoveJavascriptInterface("mapEvents");
        }

        if (e.NewElement != null)
        {
            var newElementController = e.NewElement as IWebViewController;
            newElementController.EvalRequested += OnEvalRequested;
            newElementController.EvaluateJavaScriptRequested += OnEvaluateJavaScriptRequested;
            newElementController.GoBackRequested += OnGoBackRequested;
            newElementController.GoForwardRequested += OnGoForwardRequested;

            Control.AddJavascriptInterface(new JSBridge(this), "mapEvents");
            Control.LoadUrl($"file://{System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData)}/webgl/map.html");

            UpdateMixedContentMode();
        }

        Load();
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        switch (e.PropertyName)
        {
            case "Source":
                Load();
                break;
            case "MixedContentMode":
                UpdateMixedContentMode();
                break;
        }
    }

    void Load()
    {
        if (_ignoreSourceChanges)
            return;

        if (Element.Source != null)
            Element.Source.Load(this);

        UpdateCanGoBackForward();
    }

    void OnEvalRequested(object sender, EvalRequested eventArg)
    {
        LoadUrl("javascript:" + eventArg.Script);
    }

    async Task<string> OnEvaluateJavaScriptRequested(string script)
    {
        var jsr = new JavascriptResult();

        Control.EvaluateJavascript(script, jsr);

        return await jsr.JsResult.ConfigureAwait(false);
    }

    void OnGoBackRequested(object sender, EventArgs eventArgs)
    {
        if (Control.CanGoBack())
            Control.GoBack();

        UpdateCanGoBackForward();
    }

    void OnGoForwardRequested(object sender, EventArgs eventArgs)
    {
        if (Control.CanGoForward())
            Control.GoForward();

        UpdateCanGoBackForward();
    }

    void UpdateCanGoBackForward()
    {
        if (Element == null || Control == null)
            return;
        ElementController.CanGoBack = Control.CanGoBack();
        ElementController.CanGoForward = Control.CanGoForward();
    }

    void UpdateMixedContentMode()
    {
        if (Control != null && ((int)Build.VERSION.SdkInt >= 21))
        {
            if (Element is Xamarin.Forms.WebView element)
            {
                Control.Settings.MixedContentMode = (MixedContentHandling)element.OnThisPlatform().MixedContentMode();
            }
            else
            {
                throw new InvalidCastException("Element type is not based on Xamarin.Forms.WebView");
            }
        }
    }

    class WebClient : WebViewClient
    {
        WebNavigationResult _navigationResult = WebNavigationResult.Success;
        ExtWebViewRenderer _renderer;

        public WebClient(ExtWebViewRenderer renderer)
        {
            _renderer = renderer ?? throw new ArgumentNullException("renderer");
        }

        public override void OnPageFinished(AWebView view, string url)
        {
            if (_renderer.Element == null || url == "file:///android_asset/")
                return;

            var source = new UrlWebViewSource { Url = url };
            _renderer._ignoreSourceChanges = true;
            _renderer.ElementController.SetValueFromRenderer(ExtWebView.SourceProperty, source);
            _renderer._ignoreSourceChanges = false;

            var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, source, url, _navigationResult);

            _renderer.ElementController.SendNavigated(args);

            _renderer.UpdateCanGoBackForward();

            base.OnPageFinished(view, url);
        }

        [Obsolete("OnReceivedError is obsolete as of version 2.3.0. This method was deprecated in API level 23.")]
        public override void OnReceivedError(AWebView view, ClientError errorCode, string description, string failingUrl)
        {
            _navigationResult = WebNavigationResult.Failure;
            if (errorCode == ClientError.Timeout)
                _navigationResult = WebNavigationResult.Timeout;
            base.OnReceivedError(view, errorCode, description, failingUrl);
        }

        public override void OnReceivedError(AWebView view, IWebResourceRequest request, WebResourceError error)
        {
            _navigationResult = WebNavigationResult.Failure;
            if (error.ErrorCode == ClientError.Timeout)
                _navigationResult = WebNavigationResult.Timeout;
            base.OnReceivedError(view, request, error);
        }

        [Obsolete]
        public override bool ShouldOverrideUrlLoading(AWebView view, string url)
        {
            if (_renderer.Element == null)
                return true;

            var args = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = url }, url);

            _renderer.ElementController.SendNavigating(args);
            _navigationResult = WebNavigationResult.Success;

            _renderer.UpdateCanGoBackForward();
            return args.Cancel;
        }

        #region Added overrides

        public override void DoUpdateVisitedHistory(AWebView view, string url, bool isReload)
        {
            base.DoUpdateVisitedHistory(view, url, isReload);
        }

        public override void OnFormResubmission(AWebView view, Message dontResend, Message resend)
        {
            base.OnFormResubmission(view, dontResend, resend);
        }

        public override void OnLoadResource(AWebView view, string url)
        {
            base.OnLoadResource(view, url);
        }

        public override void OnPageCommitVisible(AWebView view, string url)
        {
            base.OnPageCommitVisible(view, url);
        }

        public override void OnPageStarted(AWebView view, string url, Bitmap favicon)
        {
            base.OnPageStarted(view, url, favicon);
        }

        public override void OnReceivedClientCertRequest(AWebView view, ClientCertRequest request)
        {
            base.OnReceivedClientCertRequest(view, request);
        }

        public override void OnReceivedHttpAuthRequest(AWebView view, HttpAuthHandler handler, string host, string realm)
        {
            base.OnReceivedHttpAuthRequest(view, handler, host, realm);
        }

        public override void OnReceivedHttpError(AWebView view, IWebResourceRequest request, WebResourceResponse errorResponse)
        {
            base.OnReceivedHttpError(view, request, errorResponse);
        }

        public override void OnReceivedLoginRequest(AWebView view, string realm, string account, string args)
        {
            base.OnReceivedLoginRequest(view, realm, account, args);
        }

        public override void OnReceivedSslError(AWebView view, SslErrorHandler handler, SslError error)
        {
            base.OnReceivedSslError(view, handler, error);
        }

        public override bool OnRenderProcessGone(AWebView view, RenderProcessGoneDetail detail)
        {
            return base.OnRenderProcessGone(view, detail);
        }

        public override void OnSafeBrowsingHit(AWebView view, IWebResourceRequest request, [GeneratedEnum] SafeBrowsingThreat threatType, SafeBrowsingResponse callback)
        {
            base.OnSafeBrowsingHit(view, request, threatType, callback);
        }

        public override void OnScaleChanged(AWebView view, float oldScale, float newScale)
        {
            base.OnScaleChanged(view, oldScale, newScale);
        }

        [Obsolete]
        public override void OnTooManyRedirects(AWebView view, Message cancelMsg, Message continueMsg)
        {
            base.OnTooManyRedirects(view, cancelMsg, continueMsg);
        }

        public override void OnUnhandledInputEvent(AWebView view, InputEvent e)
        {
            base.OnUnhandledInputEvent(view, e);
        }

        public override void OnUnhandledKeyEvent(AWebView view, KeyEvent e)
        {
            base.OnUnhandledKeyEvent(view, e);
        }

        public override WebResourceResponse ShouldInterceptRequest(AWebView view, IWebResourceRequest request)
        {
            return base.ShouldInterceptRequest(view, request);
        }

        [Obsolete]
        public override WebResourceResponse ShouldInterceptRequest(AWebView view, string url)
        {
            return base.ShouldInterceptRequest(view, url);
        }

        public override bool ShouldOverrideKeyEvent(AWebView view, KeyEvent e)
        {
            return base.ShouldOverrideKeyEvent(view, e);
        }

        public override bool ShouldOverrideUrlLoading(AWebView view, IWebResourceRequest request)
        {
            return base.ShouldOverrideUrlLoading(view, request);
        }

        #endregion

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (disposing)
                _renderer = null;
        }
    }

    class JavascriptResult : Java.Lang.Object, IValueCallback
    {
        TaskCompletionSource<string> source;
        public Task<string> JsResult { get { return source.Task; } }

        public JavascriptResult()
        {
            source = new TaskCompletionSource<string>();
        }

        public void OnReceiveValue(Java.Lang.Object result)
        {
            string json = ((Java.Lang.String)result).ToString();
            source.SetResult(json);
        }
    }
}

}

Answers

Sign In or Register to comment.