Xamarin Forms HTML Label

Merhaba,

Genelde yapılan projelerde gördüğüm kadarıyla HTML desteği duyulan sayfalar webview üzerinden gösteriliyor. Aslında Xamarin Forms üzerinde CustomRenderer yapısını kullanarak, bu sayfalarımızı webview kullanmadan bir ContentPage üzerinde native olarak gösterebiliriz.

Xamarin Forms’un bir UI Framework olduğunu ve platformların native özelliklerine DependencyService ve CustomRenderer gibi yöntemlerle ulaşabildiğimizi ve platformların yeteneklerini sonuna kadar ve sorunsuz bir şekilde kullanabileceğimizi unutmamamız gerekir.

Bu örneğimizde Visual Studio for Mac kullanacağım.

Tüm Label kontrollerimizin yapacağımız CustomRenderer işleminden etkilenmemesi için kendimize özel bir Label class’ı oluşturmalıyız.


    public class HTMLLabel : Label
    {
        
    }

Şimdi iOS için CustomRenderer yazmamız gerekiyor.


[assembly: Xamarin.Forms.ExportRenderer(typeof(HTMLLabel), typeof(HtmlLabelRenderer))]
namespace FormsHTMLLabel.iOS.CustomRenderers
{
    public class HtmlLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Label> e)
        {
            base.OnElementChanged(e);

            var element = (HTMLLabel)e.NewElement;
            if (element != null &&
                Control != null)
            {
                var nsAttr = new NSAttributedStringDocumentAttributes()
                {
                    DocumentType = NSDocumentType.HTML
                };
                var html = NSData.FromString(element.Text, NSStringEncoding.Unicode);
                var nsError = new NSError();
                Control.AttributedText = new NSAttributedString(html, nsAttr, ref nsError);
            }
        }
    }
}

e.NewElement ile XF-PCL katmanında oluşturduğumuz HTMLLabel kontrolüne ulaşırız.Çünkü PCL tarafta set ettiğimiz Text özelliğine ulaşmamız gerekiyor.

Yazacağımız CustomRenderer objelerinde, eğer kullanacağımız özellikler Bindable değilse bunu Android ve iOS katmanlarda kullanamayız.

Label’ın Text özelliği zaten Bindable olduğu için bu işlemi yapmamıza gerek yok.


NSAttributedStringDocumentAttributes class’ı ile iOS’in native özelliklerini kullanabiliyoruz.
DocumentType özelliğini HTML destekleyeceğini belirtiyoruz ve Unicode karakterleri desteklemesi için NSData.FromString methodunu kullanıyoruz.
Burada dikkat etmemiz gerken yer ise Control.AttributedText kullanımı. Direkt Text özelliğini kullanırsak aslında bu kadar yaptığımız CustomRenderer işlemi boşa gidecek. Çünkü biz HTML özelliklerini destekleyen bir text yazdığımız için AttributedText özelliğini kullanmalıyız.


HTMLLabel lbl = new HTMLLabel
            {
                VerticalOptions = LayoutOptions.Center,
				Text = 
                    "<html><body><Center>" +
				   "


<h1>Heading</h1>



" +
                    "

Paragraph

" + 
                    "<i>Italic</i>
" +
                    "<b>Bold</b>
" +
                    "<u>Underline</u>
" +
                    "<font size=\"40\">Xamarin</font>" +
                    "<font color=\"red\">FORMS</font>
" +
				   "<Center></body></html>"
            };

            Content = lbl;


Şimdi Android için CustomRenderer yazmamız gerekiyor.

[assembly: Xamarin.Forms.ExportRenderer(typeof(HTMLLabel), typeof(HtmlLabelRenderer))]
namespace FormsHTMLLabel.Droid.CustomRenderers
{
    public class HtmlLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Label> e)
        {
            base.OnElementChanged(e);

			var element = (HTMLLabel)e.NewElement;
			if (element != null &&
				Control != null)
			{
                Control.SetText(Html.FromHtml(element.Text), TextView.BufferType.Spannable);
			}
        }
    }
}

Evet bazı durumlarda Android için CustomRenderer yazmak daha kolaydır bazı durumlarda ise iOS için 🙂
Yaptığımız işlemler aslında Native platformların kendini özelliklerini kullanmaktan başka bir şey değil.
Önemli olan ihtiyacımızı net bir şekilde belirlemek ve platformların dökümanlarında ihtiyacımızı aramak 🙂

Görüşmek üzere.

Yiğit

Xamarin Developer, Consultant & Architect. Community Leader and Director of Xamarin Türkiye

Post A Reply