Is there any way I can add HTML into a Xamarin.Forms page?

前端 未结 1 613
有刺的猬
有刺的猬 2021-02-14 13:41

I would like to be able to add some HTML into a Xamarin.Forms page? Is this possible? Also is it possible to add this as part of a label?

相关标签:
1条回答
  • 2021-02-14 14:13

    If you want full-blown html support, then Xamarin forms WebView would be way to go. But if you want some basic formatting support in Label as it's native counter-parts (TextView in android, and UILabel in iOS) do, you can implement renderers for that.

    Forms control

    public class HtmlLabel : Label
    {
        public static readonly BindableProperty HtmlProperty =
            BindableProperty.Create(
                "Html", typeof(string), typeof(HtmlLabel),
                defaultValue: default(string));
    
        public string Html
        {
            get { return (string)GetValue(HtmlProperty); }
            set { SetValue(HtmlProperty, value); }
        }
    }
    

    iOS renderer

    [assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
    namespace HtmlLabelApp.iOS
    {
        public class HtmlLabelRenderer : LabelRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
            {
                base.OnElementChanged(e);
    
                //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
                if (e.NewElement != null)
                    UpdateTextOnControl();
            }
    
            protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
    
                //if there is change in text or font-style, trigger update to redraw control
                if (e.PropertyName == nameof(HtmlLabel.Html))
                {
                    UpdateTextOnControl();
                }
            }
    
            void UpdateTextOnControl()
            {
                if (Control == null)
                    return;
    
                if (Element is HtmlLabel formsElement)
                {
                    //set new text with ui-style-attributes to native control (UILabel)
                    var htmlString = new NSString(formsElement.Html ?? string.Empty);
                    var htmlData = htmlString.Encode(NSStringEncoding.UTF8);
                    var attr = new NSAttributedStringDocumentAttributes
                    {
                        DocumentType = NSDocumentType.HTML
                    };
    
                    var error = new NSError();
                    var dict = new NSDictionary();
    
                    var attributedString = new NSAttributedString(htmlData, attr, out dict, ref error);
                    Control.AttributedText = attributedString;
                }
            }
        }
    }
    

    Android renderer

    [assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
    namespace HtmlLabelApp.Droid
    {
        public class HtmlLabelRenderer : LabelRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
            {
                base.OnElementChanged(e);
    
                //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
                if (e.NewElement != null)
                    UpdateTextOnControl();
            }
    
            protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
    
                //if there is change in text or font-style, trigger update to redraw control
                if (e.PropertyName == nameof(HtmlLabel.Html))
                {
                    UpdateTextOnControl();
                }
            }
    
            void UpdateTextOnControl()
            {
                if (Control == null)
                    return;
    
                if (Element is HtmlLabel formsElement)
                {
                    var htmlAsString = formsElement.Html ?? string.Empty;      // used by WebView
                    var htmlAsSpanned = Html.FromHtml(htmlAsString, FromHtmlOptions.ModeCompact); // used by TextView
    
                    Control.TextFormatted = htmlAsSpanned;
                }
            }
        }
    }
    

    Sample Usage

    <local:HtmlLabel BackgroundColor="Silver">
        <local:HtmlLabel.Html>
            <x:String>
            <![CDATA[
    
                <h1>Main Title</h1>
                <h2>A sub-title</h2>
                <p>This is some html. Look, here\'s an <u>underline</u>.</p>
                <p>Look, this is <em>emphasized.</em> And here\'s some <b>bold</b>.</p>
                <p>This is a UL list:
                <ul>
                 <li>One</li>
                 <li>Two</li>
                 <li>Three</li>
                </ul>
                <p>This is an OL list:
                <ol>
                 <li>One</li>
                 <li>Two</li>
                 <li>Three</li>
                </ol>
            ]]>
            </x:String>
        </local:HtmlLabel.Html>
    </local:HtmlLabel>
    

    0 讨论(0)
提交回复
热议问题