Xamarin.forms: [Peningkatan] Ukuran WebView ke konten

Dibuat pada 26 Jan 2018  ·  59Komentar  ·  Sumber: xamarin/Xamarin.Forms

Alasan

Formulir saat ini tidak memiliki mekanisme untuk mengukur WebView agar sesuai dengan kontennya.

Penerapan

Tambahkan properti SizeToContent yang dapat diikat ke WebView:

static readonly BindablePropertyKey SizeToContentProperty = 
BindableProperty.CreateReadOnly("SizeToContent", typeof(bool), typeof(WebView), false);

Ketika properti ini adalah true , WebView harus mencoba mengukur dirinya sendiri ke ukuran minimum yang diperlukan agar sesuai dengan konten web yang ditampilkan. Ukuran otomatis harus dilakukan hanya di sepanjang dimensi yang tidak ditentukan; misalnya, jika WidthRequest atau HorizontalOptions.Fill sedang dimainkan, WebView harus menghormati spesifikasi tersebut dan hanya mengukur dirinya sendiri secara vertikal agar sesuai dengan konten.

Kompatibilitas terbalik

Ini adalah properti/perilaku baru, jadi seharusnya tidak ada masalah kompatibilitas mundur.

Kesulitan: Tidak berjalan-jalan di taman

Ini mungkin memerlukan penggunaan fitur di https://github.com/xamarin/Xamarin.Forms/issues/1699 untuk menanyakan objek document untuk informasi ukuran.

F100 webview community-sprint high impact proposal-accepted enhancement ➕

Komentar yang paling membantu

Hai @almirvuk , saya akhirnya menggunakan ini untuk android. Bekerja dengan baik untuk saya..!

using System;
using System.Threading.Tasks;
using Android.Content;
using Android.Webkit;
using MyProject.Controls;
using MyProject.Android.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using WebView = Android.Webkit.WebView;

[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyProject.Android.Renderers
{
    public class ExtendedWebViewRenderer : WebViewRenderer
    {
        public static int _webViewHeight;
        static ExtendedWebView _xwebView = null;
        WebView _webView;

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

        class ExtendedWebViewClient : WebViewClient
        {
            WebView _webView;
            public async override void OnPageFinished(WebView view, string url)
            {
                try
                {
                    _webView = view;
                    if (_xwebView != null)
                    {

                        view.Settings.JavaScriptEnabled = true;
                        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 ExtendedWebView;
            _webView = Control;

            if (e.OldElement == null)
            {
                _webView.SetWebViewClient(new ExtendedWebViewClient());
            }

        }
    }
}

Semua 59 komentar

Kami menerapkan ini untuk iOS & Android menggunakan API platform setelah javascript terbukti tidak dapat diandalkan. Di luar kepala saya, js menambahkan jeda 50-100ms yang menyebabkan flash yang tidak sedap dipandang sebelum mengubah ukuran, ukuran DOM sering terpaut beberapa px dari bitmap yang dirender, dan mendeteksi perubahan setelah pemuatan awal memerlukan polling (atau polyfill ResizeObserver. )

Ternyata mengamati perubahan ukuran tampilan web asli itu sederhana dan mengubah ukurannya segera. Cuplikan di bawah ini berasal dari perender khusus kami yang menerapkan tampilan web baru menggunakan WKWebView alih-alih UIWebView , tetapi saya pikir konsep tersebut juga berlaku untuk perender WebView saham.

Di iOS, kami menggunakan KVO untuk melihat perubahan pada tampilan gulir yang mendasari tampilan web dan memposting perubahan ke elemen:

void ConfigureSizeChangeObserver()
{
    if (Element.AutosizeHeight) {
        SetupContentSizeObserver();
    } else {
        RemoveContentSizeObserver();
    }
}

void SetupContentSizeObserver()
{
    if (kvoToken != null) {
        return;
    }
    kvoToken = Control.AddObserver("scrollView.contentSize", NSKeyValueObservingOptions.OldNew, ScrollViewContentSizeChanged);
}

void RemoveContentSizeObserver()
{
    kvoToken?.Dispose();
    kvoToken = null;
}

void ScrollViewContentSizeChanged(NSObservedChange nsObservedChange)
{
    if (nsObservedChange.NewValue.IsEqual(nsObservedChange.OldValue)) {
        return;
    }
    var newSize = ((NSValue)nsObservedChange.NewValue).CGSizeValue;
    Element.OnContentSizeChange(new Size(newSize.Width, newSize.Height));
}

Di Android, kami membuat subkelas Android.Webkit.WebView yang memunculkan peristiwa jika ukurannya berubah setelah pembatalan:

public class DynamicSizeWebView : Android.Webkit.WebView
{
    public EventHandler SizeChanged;

    bool _observeSizeChanges;
    public bool ObserveSizeChanges {
        get => _observeSizeChanges;
        set {
            if (_observeSizeChanges != value) {
                _observeSizeChanges = value;
                if (_observeSizeChanges) {
                    OnSizeChange();
                }
            }
        }
    }

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

    protected DynamicSizeWebView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { }

    int _previousMesuredHeight = 0;

    public override void Invalidate()
    {
        base.Invalidate();
        if (ObserveSizeChanges) {
            OnSizeChange();
        }
    }

    void OnSizeChange()
    {
        var newHeight = ContentHeight;
        if (newHeight > 0 && _previousMesuredHeight != newHeight) {
            SizeChanged?.Invoke(this, EventArgs.Empty);
            _previousMesuredHeight = newHeight;
        }
    }
}

Kami kemudian menggunakan tampilan web khusus seperti ini:

protected override void OnElementChanged(ElementChangedEventArgs<EnhancedWebView> e)
{
    base.OnElementChanged(e);
    ...
    if (e.NewElement is IEnhancedWebViewController newElement) {
        if (Control == null) {
            var webView = new DynamicSizeWebView(Forms.Context);
            webView.SetWebViewClient(new Client(this));
            webView.Settings.JavaScriptEnabled = true;
            webView.SizeChanged += WebView_SizeChanged;
            SetNativeControl(webView);
        }
        ...
    }
}

void WebView_SizeChanged(object sender, EventArgs e)
{
    Element.OnContentSizeChange(new Size(Control.MeasuredWidth, Control.ContentHeight));
}

Saya sudah lama tidak menggunakan Xamarin.Forms.WebView atau melihat sumbernya, tapi saya rasa ini tidak akan sulit untuk di-backport. Saya mungkin bisa mencoba dalam satu atau dua minggu ke depan.

@michaeldwan Luar biasa. Jika ada cara yang lebih mendekati asli untuk membuatnya bekerja, maka itulah yang ingin kami gunakan. Saya tidak ingin bergantung pada JS untuk apa pun kecuali kita benar-benar harus melakukannya.

Ya jelas tidak menggunakan JS IMO. Apakah kami memiliki petunjuk apakah ini mungkin di semua platform? kita harus menyelidiki.

Saya memiliki kode untuk Android, iOS, dan Mac. Saya belum pernah melakukan UWP, tetapi kami selalu dapat mundur ke JS jika tidak ada API asli yang lebih baik. Saya akan menyusun PR untuk platform yang saya tahu lalu menyelidiki yang lain. cc @davidortinau

@michaeldwan baru saja melakukan pemeriksaan cepat untuk melihat apakah Anda masih mengerjakan ini. Jika tidak, kami dapat menambahkannya kembali ke kolam yang tersedia.

Bump @michaeldwan

@michaeldwan Saya telah menerapkan penyaji khusus untuk masalah ini berdasarkan jawaban di forum Xamarin. Saya perhatikan bahwa tinggi tampilan web terlalu panjang dibandingkan dengan konten di beberapa proyek. Yang aneh adalah saya tidak dapat mereproduksi ini dalam proyek terpisah. Apakah ini bug di Xamarin Android sendiri?

@michaeldwan Ada kemajuan? Terima kasih!

Saya minta maaf atas jawaban yang lambat. Saya tidak akan bisa menyelesaikan ini dalam waktu dekat. Jika ini masih terbuka dalam beberapa bulan saya akan mencoba dan membungkusnya.

Bump @michaeldwan

Apakah ada rencana untuk menambahkan ini ke peta jalan?

@michaeldwan , apakah ada berita tentang ini? Jika Anda memiliki implementasi dan memerlukan bantuan untuk pengujian, peninjauan, dll, beri tahu kami.

Apakah sudah ada pembaruan tentangnya?

Tolong tutup masalah ini..!

@PaulsonMac menutup masalah? apakah itu diselesaikan?

@Ali-Syed, sebenarnya saya ingin ini diselesaikan.. Maaf salah ketik

Ada berita tentang yang satu ini? :)

Hai @almirvuk , saya akhirnya menggunakan ini untuk android. Bekerja dengan baik untuk saya..!

using System;
using System.Threading.Tasks;
using Android.Content;
using Android.Webkit;
using MyProject.Controls;
using MyProject.Android.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using WebView = Android.Webkit.WebView;

[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyProject.Android.Renderers
{
    public class ExtendedWebViewRenderer : WebViewRenderer
    {
        public static int _webViewHeight;
        static ExtendedWebView _xwebView = null;
        WebView _webView;

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

        class ExtendedWebViewClient : WebViewClient
        {
            WebView _webView;
            public async override void OnPageFinished(WebView view, string url)
            {
                try
                {
                    _webView = view;
                    if (_xwebView != null)
                    {

                        view.Settings.JavaScriptEnabled = true;
                        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 ExtendedWebView;
            _webView = Control;

            if (e.OldElement == null)
            {
                _webView.SetWebViewClient(new ExtendedWebViewClient());
            }

        }
    }
}

@PaulsonMac terima kasih, dan untuk ios?

Anda beruntung, saya bekerja keras selama berhari-hari ini.. Ini dia..!

using System;
using Foundation;
using MyProject.Controls;
using MyProject.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyProject.iOS.Renderers
{
    class ExtendedWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            try
            {
                base.OnElementChanged(e);

                if (NativeView != null)
                {
                    var webView = (UIWebView)NativeView;

                    webView.Opaque = false;
                    webView.BackgroundColor = UIColor.Clear;
                }

                Delegate = new ExtendedUIWebViewDelegate(this);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Error at ExtendedWebViewRenderer OnElementChanged: " + ex.Message);
            }
        }
    }

    class ExtendedUIWebViewDelegate : UIWebViewDelegate
    {
        ExtendedWebViewRenderer webViewRenderer;

        public ExtendedUIWebViewDelegate(ExtendedWebViewRenderer _webViewRenderer = null)
        {
            webViewRenderer = _webViewRenderer ?? new ExtendedWebViewRenderer();
        }

        public override async void LoadingFinished(UIWebView webView)
        {
            try
            {
                var _webView = webViewRenderer.Element as ExtendedWebView;
                if (_webView != null)
                {
                    await System.Threading.Tasks.Task.Delay(100); // wait here till content is rendered
                    _webView.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Error at ExtendedWebViewRenderer LoadingFinished: " + ex.Message);
            }
        }
    }
}

Anda harus menyetel permintaan tinggi ke beberapa nilai seperti 40 di XAML untuk iOS saja..

@almirvuk , apakah kode-kode itu berfungsi ..?

Ya terima kasih! Ini berfungsi dengan baik untuk masalah ketinggian dinamis.

Senang mengetahui itu.. Terima kasih!

Terima kasih telah memposting kode teman-teman. UWP juga akan bagus - akan mencoba dan mencobanya.

Di sinilah aku mendarat. Tahu sedikit tentang UWP jadi jangan ragu untuk menyarankan perbaikan, tetapi ini tampaknya bekerja dengan cukup baik. Perhatikan bahwa dalam kasus saya, saya meneruskan string HTML dari kontrol khusus saya ke render/"navigasi", jika Anda membuka halaman yang sebenarnya, gunakan saja Control.Navigate(Uri source) sebagai gantinya.

    public class ExtendedWebViewRenderer : ViewRenderer<ExtendedWebView, Windows.UI.Xaml.Controls.WebView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ExtendedWebView> e)
        {
            try
            {
                base.OnElementChanged(e);

                if (e.OldElement != null && Control != null)
                {
                    Control.NavigationCompleted -= OnWebViewNavigationCompleted;
                }

                if (e.NewElement != null)
                {
                    if (Control == null)
                    {
                        SetNativeControl(new Windows.UI.Xaml.Controls.WebView());
                    }

                    Control.NavigationCompleted += OnWebViewNavigationCompleted;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error at ExtendedWebViewRenderer OnElementChanged: " + ex.Message);
            }
        }

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

            if (Element is ExtendedWebView element && e.PropertyName.Equals(nameof(ExtendedWebView.Html)) && !string.IsNullOrWhiteSpace(element.Html))
                Control.NavigateToString(element.Html);
        }

        private async void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
        {
            if (!args.IsSuccess)
                return;

            var heightString = await Control.InvokeScriptAsync("eval", new[] {"document.body.scrollHeight.toString()" });
            if (int.TryParse(heightString, out int height))
            {
                Element.HeightRequest = height;
            }

            var widthString = await Control.InvokeScriptAsync("eval", new[] {"document.body.scrollWidth.toString()" });
            if (int.TryParse(widthString, out int width))
            {
                Element.WidthRequest = width;
            }
        }
    }

Bagus, saya tidak menggunakan UWP tapi saya yakin ini akan membantu pengembang lain. Terima kasih!

Itu tidak berfungsi untuk saya, tinggalkan ruang kosong setelah konten tampilan web, dapatkah Anda membantu saya?

Senang mengetahui itu.. Terima kasih!

tolong aku!! :(

KVO tidak berfungsi. Jika halaman web mengubah ukuran tingginya sehingga lebih kecil dari tinggi bingkai UIWebView, Anda tidak akan diberi tahu tentang perubahan ini. Saya terkejut Apple tidak mendukung fitur ini di luar kotak, jadi kami harus menemukan solusi peretasan yang tidak berfungsi.

Saya pikir ruang lingkup peningkatan ini perlu didiskusikan. Kita bisa menggunakan JavaScript untuk mendapatkan perubahan ketinggian, tetapi ini hanya akan berfungsi selama JS berfungsi. Dalam kasus saya, saya memerlukan pemberitahuan perubahan untuk HTML yang saya berikan sebagai lawan dari URL jarak jauh, jadi JS lebih mungkin berfungsi untuk saya. Saya berasumsi ini juga berlaku untuk kebanyakan orang. Kami masih dapat menyediakan implementasi JS dan mendokumentasikan keandalannya.

Yang mengatakan, Xamarin harus memperlakukan ini sebagai item prioritas tinggi. Jika pengguliran CollectionView tidak membaik bagi saya (#7152), menggunakan WebView untuk memuat label yang dikaitkan dengan kompleks adalah pilihan yang lebih baik saat membuat sel daripada pekerjaan Label/Span. Tentu saja, ada juga #4527.

@almirvuk @PaulsonMac, adakah yang tahu cara memperbarui kode iOS untuk menggunakan WkWebViewRenderer? UIWebView akan segera usang karena Apple akan mulai menolak aplikasi yang menggunakannya.

Upaya saya saat ini tidak berhasil:

public class ExtendedWebViewRenderer : WkWebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            try
            {
                base.OnElementChanged(e);

                if (NativeView != null)
                {
                    var webView = (WKWebView)NativeView;

                    webView.Opaque = false;
                    webView.BackgroundColor = UIColor.Clear;
                }

                NavigationDelegate = new ExtendedNavigationDelegate(this);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error at ExtendedWebViewRenderer OnElementChanged: " + ex.Message);
            }
        }
    }

    public class ExtendedNavigationDelegate : WKNavigationDelegate
    {
        private readonly ExtendedWebViewRenderer webViewRenderer;

        public ExtendedNavigationDelegate(ExtendedWebViewRenderer webViewRenderer = null)
        {
            this.webViewRenderer = webViewRenderer ?? new ExtendedWebViewRenderer();
        }

        public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
        {
            try
            {
                var extWebView = webViewRenderer.Element as ExtendedWebView;
                if (extWebView != null)
                {
                    await System.Threading.Tasks.Task.Delay(100); // wait here till content is rendered
                    extWebView.HeightRequest = (double)webView.ScrollView.ContentSize.Height;

                    webView.ScrollView.FlashScrollIndicators(); // no direct way to ALWAYS show the scrollbar, so just going to flash it upon load to show user it is there and scrollable
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error at ExtendedWebViewRenderer LoadingFinished: " + ex.Message);
            }
        }
    }

Hai @mzhukovs , mungkin Anda harus mengikuti utas ini: https://github.com/xamarin/Xamarin.Forms/issues/7323

@almirvuk terima kasih tapi itu tidak ada hubungannya dengan ukuran WKWebView untuk menyesuaikan kontennya secara otomatis, kecuali saya melewatkan sesuatu?

Maaf, saya kira Anda bertanya tentang dukungan WKWebView terkait pemberitahuan masalah penerbitan Apple itu.

@PaulsonMac solusi ini tidak berfungsi di iOS (lagi), di Xamarin.Forms 4.2.0.709249, WebView dengan tinggi konten dinamis tidak menyebar tinggi, pada XF 3.6 masih berfungsi seperti pesona.

:( - jika mengatur ketinggian default dalam kode, maka itu berfungsi

Apakah ada pembaruan untuk implementasi iOS? Saat ini saya terjebak dengan ukuran yang sama untuk masalah konten yang bermigrasi dari UIWebView

@Predatorie Xamarin Forms mengimplementasikan tampilan teks HTML dengan Label dalam rilis terbaru. Anda hanya perlu menerapkan TextType = Html.

Silakan merujuk: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label#display -html

Bisa jadi solusi yang berbeda dari apa yang dibahas di thread ini.

Untuk UWP, saya mulai dengan solusi mzhukovs di atas, tetapi tidak memuat beberapa aset lokal (misalnya file style sheet) ke halaman karena tidak mengetahui URL dasar. Jadi penyaji saya mewarisi dari Xamarin.Forms.Platform.UWP.WebViewRenderer dan hanya melakukan pembaruan ukuran pada NavigationCompleted.

Saya kira saya akan memasukkan seluruh kelas untuk kelengkapan.

ExtendedWebView (dalam proyek portabel) terlihat seperti ini:
public class ExtendedWebView : WebView { }

(XAML)

<controls:ExtendedWebView x:Name="wvApplication" WidthRequest="-1" HeightRequest="-1" 
      VerticalOptions="StartAndExpand" HorizontalOptions="FillAndExpand">
    <WebView.Source>
        <HtmlWebViewSource Html="{Binding ApplicationHtml}" />
    </WebView.Source>
</controls:ExtendedWebView>
[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyNamespace
{
    public class ExtendedWebViewRenderer : Xamarin.Forms.Platform.UWP.WebViewRenderer
    {

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

                if (e.OldElement != null && Control != null)
                {
                    Control.NavigationCompleted -= Control_NavigationCompleted;
                }

                if (e.NewElement != null && Control != null)
                {
                    Control.NavigationCompleted += Control_NavigationCompleted;
                }
            } catch (Exception ex)
            {
                Console.WriteLine($"Error at ExtendedWebViewRenderer {nameof(OnElementChanged)}: " + ex.Message);
            }
        }

        private async void Control_NavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, Windows.UI.Xaml.Controls.WebViewNavigationCompletedEventArgs args)
        {
            if (args.IsSuccess)
            {
                await UpdateSize();
            }
        }

        private async Task UpdateSize()
        {
            try
            {
                var heightString = await Control.InvokeScriptAsync("eval", new[] { "document.body.scrollHeight.toString()" });
                if (int.TryParse(heightString, out int height))
                {
                    Element.HeightRequest = height;
                }

                var widthString = await Control.InvokeScriptAsync("eval", new[] { "document.body.scrollWidth.toString()" });
                if (int.TryParse(widthString, out int width))
                {
                    Element.WidthRequest = width;
                }
            } catch (Exception ex)
            {
                Console.WriteLine($"Error at ExtendedWebViewRenderer {nameof(UpdateSize)}: " + ex.Message);
            }
        }
    }
}

Dua tahun kemudian, ini masih menjadi masalah di Xamarin Forms.

Adakah yang menemukan cara untuk mengimplementasikan ini di iOS dengan WkWebViewRenderer? @mzhukovs :) ?

Saya telah mencoba dengan CustomWKNavigationDelegate di WkWebViewRenderer dan mendelegasikan metode tetapi DidFinishNavigation (...) tidak pernah dipanggil. Saya menggunakan "lokal", data Html sebagai sumber untuk WebView ... Adakah panduan untuk ini? Terima kasih!

Ini adalah apa yang saya miliki dan itu bekerja dengan cukup baik.

Hai @eevahr , Saya menggunakan pendekatan serupa tetapi DidFinishNavigation tidak pernah dipanggil dengan html lokal sebagai sumber untuk tampilan web. Apakah Anda menggunakan url dengan tampilan web atau?

Saya mendapatkan html dari api dan mengatur sumbernya secara manual. Jadi bukan lokal tetapi tidak ada url yang dimuat juga. Saya menduga Anda sudah familiar dengan perender khusus dan apa yang tidak, tetapi apakah Anda yakin menggunakan perender? :)

@eevahr Sama seperti saya... Ya, karena saya mendapatkan breakpoint di Renderer dan Custom delegasi ctors. :)

saya ingin ini juga!

Halo kawan-kawan! Adakah yang pernah mencoba solusi ini sebelumnya - https://stackoverflow.com/a/56304192/10329199 di WKWebView untuk mengukur konten secara dinamis ...??

@PaulsonMac Saya memiliki semacam bug aneh... DidFinishNavigation tidak pernah dipicu dengan konten HTML lokal. :(

Pada akhirnya kami berhasil menggunakan pendekatan hibrida. Untuk iOS kami menggunakan fitur HTML dari komponen Label. Secara otomatis menyesuaikan ketinggiannya dengan benar dan menerima berbagai macam tag HTML. Ini bekerja dengan baik. Tidak begitu banyak untuk Android, ia memiliki kumpulan HTML yang diterima yang jauh lebih terbatas dan tidak menyesuaikan ketinggian dengan baik untuk konten. Dalam hal ini, kami menggunakan perender kustom tinggi dinamis untuk tampilan web. Sejauh ini ini berhasil bagi kami.

Apakah ada pembaruan tentang kapan ini akan diterapkan?

contoh sumber di android?

Hai @almirvuk , saya akhirnya menggunakan ini untuk android. Bekerja dengan baik untuk saya..!

using System;
using System.Threading.Tasks;
using Android.Content;
using Android.Webkit;
using MyProject.Controls;
using MyProject.Android.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using WebView = Android.Webkit.WebView;

[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyProject.Android.Renderers
{
    public class ExtendedWebViewRenderer : WebViewRenderer
    {
        public static int _webViewHeight;
        static ExtendedWebView _xwebView = null;
        WebView _webView;

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

        class ExtendedWebViewClient : WebViewClient
        {
            WebView _webView;
            public async override void OnPageFinished(WebView view, string url)
            {
                try
                {
                    _webView = view;
                    if (_xwebView != null)
                    {

                        view.Settings.JavaScriptEnabled = true;
                        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 ExtendedWebView;
            _webView = Control;

            if (e.OldElement == null)
            {
                _webView.SetWebViewClient(new ExtendedWebViewClient());
            }

        }
    }
}

Saya menggunakan kode ini, tetapi konten html saya tidak ditampilkan, saya telah men-debug kode ini, tetapi tidak ada pass url yang tepat dalam string url, tolong beri tahu saya.

Apakah ada solusi yang berfungsi untuk WkWebview?

Saya ingin ini diterapkan sebelum ditayangkan dalam beberapa hari. Mohon solusi?

@PaulsonMac ... jika Anda melihat komentar saya, kami telah berhasil menggunakan pendekatan hybrid. Dalam kode Formulir Xamarin berdasarkan platform, kami akan menggunakan kemampuan HTML bawaan dari komponen Label atau, untuk Android, menggunakan solusi kontrol khusus seperti yang disebutkan di atas.

Terimakasih atas tanggapan Anda. Tetapi karena kami memiliki gambar dalam HTML, saya pikir kami tidak dapat melanjutkan dengan jenis teks HTML Label Xamarin.

@almirvuk , DidFinishNavigation juga tidak mengenai saya. Bisakah Anda memberi tahu saya bagaimana Anda menyelesaikan ini?

Terima kasih Yesus! Berhasil di iOS!

[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace Project.iOS.Renderers
{
    class ExtendedWebViewRenderer : WkWebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            try
            {
                base.OnElementChanged(e);

                NavigationDelegate = new ExtendedWKWebViewDelegate(this);

               // For fixing white flash issue in webview on dark themes/backgrounds and disable webview's scrolling
               if (NativeView != null)
                {
                    var webView = (WKWebView)NativeView;

                    webView.Opaque = false;
                    webView.BackgroundColor = UIColor.Clear;
                    webView.ScrollView.ScrollEnabled = false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error at ExtendedWebViewRenderer OnElementChanged: " + ex.Message);
            }
        }
    }

    class ExtendedWKWebViewDelegate : WKNavigationDelegate
    {
        ExtendedWebViewRenderer webViewRenderer;

        public ExtendedWKWebViewDelegate(ExtendedWebViewRenderer _webViewRenderer)
        {
            webViewRenderer = _webViewRenderer ?? new ExtendedWebViewRenderer();
        }

        public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
        {
            var wv = webViewRenderer.Element as ExtendedWebView;
            if (wv != null && webView != null)
            {
                await System.Threading.Tasks.Task.Delay(100); // wait here till content is rendered
                if (webView.ScrollView != null && webView.ScrollView.ContentSize != null)
                {
                    wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
                }
            }
        }

Sebelumnya saya memiliki layar putih di area tampilan web dan juga ketinggian dinamis tidak berfungsi. Tapi sekarang ini berfungsi dengan baik!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat