How to update custom WebView height request when content is shrunk

北慕城南 提交于 2021-02-16 21:14:35

问题


The problem occurs on Android.

I have implemented a custom renderer for a WebView to get the capability of resizing the height request base on its content.

I took this from a xamarin forum post.

[assembly: ExportRenderer(typeof(AutoHeightWebView), typeof(AutoHeightWebViewRenderer))]
namespace MyProject.Droid.Renderers
{
    public class AutoHeightWebViewRenderer : WebViewRenderer
    {

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

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

            if (e.NewElement is AutoHeightWebView webViewControl)
            {
                if (e.OldElement == null)
                {
                    Control.SetWebViewClient(new ExtendedWebViewClient(webViewControl));
                }
            }
        }

        class ExtendedWebViewClient : Android.Webkit.WebViewClient
        {
            private readonly AutoHeightWebView _control;

            public ExtendedWebViewClient(AutoHeightWebView control)
            {
                _control = control;
            }

            public override async void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                if (_control != null)
                {
                    int i = 10;
                    while (view.ContentHeight == 0 && i-- > 0) // wait here till content is rendered
                    {
                        await System.Threading.Tasks.Task.Delay(100);
                    }

                    _control.HeightRequest = view.ContentHeight;
                }

                base.OnPageFinished(view, url);
            }
        }
    }
}

Based on a certain logic, I change the source of the WebView and use the custom renderer to resize the view.

This works when the size is increased but not when the content size is smaller than the one before...

The be clearer, if I set the source of the WebView to a html file that is 200px height and change it to a html file that is 1000px, it works fine and I can see all the content. BUT, if I try to go back to my 200px html file, I get a 800px blank space underneath since the content doesn't change on the view.ContentHeight and keep the value of 1000px.

I followed this issue/thread and didn't find a solution to resolve this problem : https://github.com/xamarin/Xamarin.Forms/issues/1711

I have seen a lot of topics on Android saying that we need to recreate the webview. Is there any other solution?


回答1:


I found a way to do it based on this thread.

I first tried with a JS command that returns the body height : document.body.scrollHeight. The problem was the same, it always returned the largest size, but never decreased the size.

As the JS command have no problem to increase the size, I had to set the height to 0, set a 100ms delay (arbitrary) and then get the height of the HTML with the JS command above and set the HeightRequest of the view.

With this, the HTML body height will not decrease... It will always start from 0 and increase to the HTML body size.

Final result :

public class AutoHeightWebViewRenderer : WebViewRenderer
{
    static AutoHeightWebView _xwebView = null;

    public AutoHeightWebViewRenderer(Android.Content.Context context) : base(context)
    {
    }

    class DynamicSizeWebViewClient : WebViewClient
    {
        public async override void OnPageFinished(Android.Webkit.WebView view, string url)
        {
            try
            {
                if (_xwebView != null)
                {
                    view.Settings.JavaScriptEnabled = true;
                    view.Settings.DomStorageEnabled = true;
                    _xwebView.HeightRequest = 0d;

                    await Task.Delay(100);

                    string result = await _xwebView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
                    _xwebView.HeightRequest = Convert.ToDouble(result);
                }
                base.OnPageFinished(view, url);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{ex.Message}");
            }
        }
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
    {
        base.OnElementChanged(e);
        _xwebView = e.NewElement as AutoHeightWebView;

        if (e.OldElement == null)
        {
            Control.SetWebViewClient(new DynamicSizeWebViewClient());
        }
    }
} 


来源:https://stackoverflow.com/questions/60399897/how-to-update-custom-webview-height-request-when-content-is-shrunk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!