Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

How to change HybridWebView Uri dynamically?

GsJurenGsJuren Member ✭✭

I have a HybridWebView in my app and i need to change the uri dynamically (When the user click at some menu the uri changes), but it does not change at all... I use WebView and it works great, but when I use the HybridWebView the Uri is not changing.

Best Answers

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    Accepted Answer

    I use WebView and it works great, but when I use the HybridWebView the Uri is not changing.

    Did you use the Control.LoadUrl(uri) method to load the url? The uri can only be updated in the native platform. Try to override the OnElementPropertyChanged method to update the Uri in the custom renderer class.

    Check the code:

    Custom WebView class

    public class CustomWebView : WebView
    {
        public static readonly BindableProperty UriProperty = BindableProperty.Create(
            propertyName: "Uri",
            returnType: typeof(string),
            declaringType: typeof(CustomWebView),
            defaultValue: default(string));
    
        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }
        ...
    }
    

    Csutom WebViewRenderer class

    [assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
    namespace TestApplication_2.Droid
    {
        public class CustomWebViewRenderer : WebViewRenderer
        {
            Context _context;
            public CustomWebViewRenderer(Context context) : base(context)
            {
                _context = context;
            }
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null)
                {
                    _url = ((CustomWebView)Element).Uri;
                    ...
                    Control.LoadUrl($"file:///android_asset/Content/{((CustomWebView)Element).Uri}");
                }
            }
    
            string _url;
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
    
                if (((CustomWebView)Element).Uri != _url)
                {
                    Control.LoadUrl($"file:///android_asset/Content/{((CustomWebView)Element).Uri}");
    
                    _url = ((CustomWebView)Element).Uri;
                }
            }
        }
    }
    

    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

  • GsJurenGsJuren Member ✭✭
    Accepted Answer

    I just resolved it using the method you mentioned, but like this:

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

            if (Control.Url != null)
            {
                var idn = new System.Globalization.IdnMapping();
                var dotnetUri = new System.Uri(Element.Uri);
                _url = ((HybridWebView)Element).Uri;
    
                NSUrl nsUrl = new NSUrl(dotnetUri.Scheme, idn.GetAscii(dotnetUri.DnsSafeHost), dotnetUri.PathAndQuery);
                Control.LoadRequest(new NSUrlRequest(nsUrl));
            }
        }`
    

    Thank you so much for helping.

Answers

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    Accepted Answer

    I use WebView and it works great, but when I use the HybridWebView the Uri is not changing.

    Did you use the Control.LoadUrl(uri) method to load the url? The uri can only be updated in the native platform. Try to override the OnElementPropertyChanged method to update the Uri in the custom renderer class.

    Check the code:

    Custom WebView class

    public class CustomWebView : WebView
    {
        public static readonly BindableProperty UriProperty = BindableProperty.Create(
            propertyName: "Uri",
            returnType: typeof(string),
            declaringType: typeof(CustomWebView),
            defaultValue: default(string));
    
        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }
        ...
    }
    

    Csutom WebViewRenderer class

    [assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
    namespace TestApplication_2.Droid
    {
        public class CustomWebViewRenderer : WebViewRenderer
        {
            Context _context;
            public CustomWebViewRenderer(Context context) : base(context)
            {
                _context = context;
            }
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null)
                {
                    _url = ((CustomWebView)Element).Uri;
                    ...
                    Control.LoadUrl($"file:///android_asset/Content/{((CustomWebView)Element).Uri}");
                }
            }
    
            string _url;
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
    
                if (((CustomWebView)Element).Uri != _url)
                {
                    Control.LoadUrl($"file:///android_asset/Content/{((CustomWebView)Element).Uri}");
    
                    _url = ((CustomWebView)Element).Uri;
                }
            }
        }
    }
    

    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

  • GsJurenGsJuren Member ✭✭

    Hey man, no, i think i do not use this. Actually, i need it in the iOS part, is the same way? Or there is another way to do that?

  • GsJurenGsJuren Member ✭✭
    Accepted Answer

    I just resolved it using the method you mentioned, but like this:

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

            if (Control.Url != null)
            {
                var idn = new System.Globalization.IdnMapping();
                var dotnetUri = new System.Uri(Element.Uri);
                _url = ((HybridWebView)Element).Uri;
    
                NSUrl nsUrl = new NSUrl(dotnetUri.Scheme, idn.GetAscii(dotnetUri.DnsSafeHost), dotnetUri.PathAndQuery);
                Control.LoadRequest(new NSUrlRequest(nsUrl));
            }
        }`
    

    Thank you so much for helping.

Sign In or Register to comment.