Как обновить пользовательский запрос высоты WebView, когда содержимое сокращается - PullRequest
2 голосов
/ 25 февраля 2020

Проблема возникает на Android.

Я реализовал пользовательский рендерер для WebView, чтобы получить возможность изменения размера базы запросов высоты по его содержимому.

Я взял это из сообщения на форуме xamarin.

[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);
            }
        }
    }
}

Исходя из определенной логики c, я изменяю источник WebView и использую пользовательский рендер для изменения размера представления.

Это работает, когда размер увеличивается, но не когда размер содержимого меньше, чем предыдущий ...

Будет понятнее, если я установлю источник WebView в файл html, который Высота 200px и измените его на html файл, который составляет 1000px, он отлично работает, и я могу видеть все содержимое. НО, если я попытаюсь go вернуться к моему файлу размером 200px html, я получу пустое пространство размером 800px внизу, так как содержимое на view.ContentHeight не изменится и сохранит значение 1000px.

Я следил за этой проблемой / темой и не нашел решения, чтобы решить эту проблему: https://github.com/xamarin/Xamarin.Forms/issues/1711

Я видел много тем на Android говоря, что нам нужно воссоздать веб-просмотр. Есть ли другое решение?

1 Ответ

0 голосов
/ 10 марта 2020

Я нашел способ сделать это, основываясь на этой теме .

Сначала я попытался с помощью команды JS, которая возвращает рост: document.body.scrollHeight. Проблема была та же, она всегда возвращала самый большой размер, но никогда не уменьшала размер.

Поскольку у команды JS нет проблем с увеличением размера, мне пришлось установить высоту на 0, установить Задержка 100 мс (произвольно), а затем получить высоту HTML с помощью команды JS выше и установить HeightRequest вида.

При этом высота тела HTML не будет уменьшаться ... Он всегда начинается с 0 и увеличивается до размера тела HTML.

Окончательный результат:

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());
        }
    }
} 
...