Zdeněk Gromnica
Zdeněk Gromnica

Reputation: 884

Xamarin.Forms: Page with CSS transformations and JS swiping doesn't work in Android WebView custom renderer, when it does in Chrome

What could be the cause of a HTML page loaded over HTTPS with CSS transformations and JavaScript that uses “swiping” to not work in a Xamarin.Forms Android WebView custom renderer?

The page works fine in: Chrome on Android, Xamarin.Android WebView, Xamarin.Forms WebView.

Only when using a WebView custom renderer on Android according to the official tutorial does the page stop working.

Specifically, it's pages like these that fail to work for some reason: https://www.irozhlas.cz/fotogalerie/7693434?fid=8301190

Found another type of pages that doesn't display correctly in an Android WebView custom renderer: https://www.irozhlas.cz/ekonomika/kalkulacka-socialni-davky-exekuce_1811280900_jab – this leads me to believe it's a CSS issue, not a JS one.

I understand this is quite a narrow scope, but I'm sure others must have run into similar problems.

I have tried:

Using Xamarin.Forms with a custom renderer for the WebView should have been the equivalent of using Xamarin.Android, but upon further investigation, a Xamarin.Android project with a WebView works fine with the page, and so does the default Xamarin.Forms WebView, thus this seems to be a Xamarin.Forms WebView custom renderer specific problem.

Upvotes: 1

Views: 591

Answers (1)

Zdeněk Gromnica
Zdeněk Gromnica

Reputation: 884

One solution I've found is to create the Android WebView inside a custom page renderer for Android. In this example, the page with the WebView is called MyPage.

On other platforms, you can use the regular MyPage Xamarin.Forms.Page with Xamarin.Forms.WebView, or WebView custom renderers. As mentioned in the question, on Android, the custom renderer for the WebView has problems with certain kinds of pages.

using Android.Content;
using Xamarin.Forms.Platform.Android;
using Android.Webkit;
using Android.Widget;

[assembly: Xamarin.Forms.ExportRenderer(typeof(MyPage), typeof(MyPageRenderer))]
namespace MyXamarinApp.Droid
{
    public class MyPageRenderer : PageRenderer
    {
        WebView webView;

        public MyPageRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }

            webView = new WebView(this.Context);

            // If you're using AXML to “inflate” the layout, you would use something like this instead:
            //webView = FindViewById<WebView>(Resource.Id.webview);

            // Important: LayoutParameters don't do anything for the layout (because the parent Xamarin.Forms page is a FrameLayout and doesn't do any automatic layout), but leaving this out is what causes the problems
            webView.LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.FillParent, LayoutParams.FillParent);

            // Here you can set the WebView settings, WebViewClient, CookieManager, AddJavascriptInterface etc.
            webView.Settings.JavaScriptEnabled = true;

            webView.LoadUrl("https://www.example.com/");

            this.AddView(webView);

            /*// The following works but breaks Xamarin.Forms:
            Activity activity = this.Context as Activity;
            activity.SetContentView(webView);*/
        }

        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            base.OnLayout(changed, left, top, right, bottom);

            webView.Layout(left, top, right, bottom); // Important because LayoutParameters doesn't have an effect
        }
    }
}

It looks like leaving out the line webView.LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.FillParent, LayoutParams.FillParent); is what causes the WebView problems. Perhaps this is what's missing in the Xamarin.Forms custom renderer?

Upvotes: 1

Related Questions