Search code examples
c#xamarinxamarin.formsxamarin.android

Xamarin Html label scrollable


Im making a novel reader app.

And i have a html which is the chapter.

I have made a custom htmlLabel that will containe tha html

The problem is that the size of the label is only as big as the screan all other text stay hidden

I have the label inside a scrollview but even so it only expand to the size of the screan for some reasion

Here is my custom label renderer. Now i know i could use a webview but i still want a label instead.

sing System;
using System.ComponentModel;
using Android.Content;
using Android.Support.V4.Text;
using Android.Text;
using Android.Widget;
using Comic.Viewer.Controllers;
using Comic.Viewer.Droid.Renderer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ClickableHtmlLabel), typeof(ClickableHtmlLabelRenderer))]
namespace Comic.Viewer.Droid.Renderer
{
   public class ClickableHtmlLabelRenderer : LabelRenderer
    {
        public ClickableHtmlLabelRenderer(Context context) : base(context)
        {

        }


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

            Control?.SetText(HtmlCompat.FromHtml(Element.Text, HtmlCompat.FromHtmlModeLegacy), TextView.BufferType.Spannable);
        }

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

            if (e.PropertyName == Label.TextProperty.PropertyName)
            {
                Control?.SetText(HtmlCompat.FromHtml(Element.Text, HtmlCompat.FromHtmlModeLegacy), TextView.BufferType.Spannable);
            }

            var el = Element as ClickableHtmlLabel;
            this.Click += new EventHandler((o, sender) =>
            {
                el.Clicked();

            });
        }
    }
} 

Solution

  • You could use custom renderer to create HtmlLabel. And then put the HtmlLabel inside a ScrollView. It would make the HtmlLabel scrollable. I make a code sample for your reference.

    HtmlLabel.cs

    public class HtmlLabel : Label
    {
    }
    

    HtmlLabelRenderer.cs

    [assembly: ExportRenderer(typeof(HtmlLabel), typeof(HtmlLabelRenderer))]
    namespace XamarinDemo.Droid.Renderers
    {
     class HtmlLabelRenderer : LabelRenderer
     {
        public HtmlLabelRenderer(Context context) : base(context)
        {
    
        }
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
    
            if (Control != null && e.NewElement != null)
            {
                UpdateText();
            }
        }
    
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
    
            if (e.PropertyName == nameof(HtmlLabel.Text))
            {
                UpdateText();
            }
        }
    
        void UpdateText()
        {
            if (string.IsNullOrWhiteSpace(Element?.Text))
            {
                Control.Text = string.Empty;
                return;
            }
    
            Control.TextFormatted = Build.VERSION.SdkInt >= BuildVersionCodes.N
                ? Html.FromHtml(Element.Text, FromHtmlOptions.ModeCompact)
    #pragma warning disable CS0618 // Type or member is obsolete
                : Html.FromHtml(Element.Text);
    #pragma warning restore CS0618 // Type or member is obsolete
    
            Control.MovementMethod = Android.Text.Method.LinkMovementMethod.Instance;
         }
      }
    

    Uasge:

     <ContentPage.Content>
        <ScrollView>
            <control:HtmlLabel x:Name="htmlLabel" FontSize="Large"/>
        </ScrollView>
     </ContentPage.Content> 
    

    Set the html text.

      htmlLabel.Text = @"<!DOCTYPE html>
    <html>
    <head>
    <title>Page Title</title>
    </head>
    <body>
    
    <h1>Starting.</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>
    <h1>This is a Heading</h1>
    <p>Ending.</p>
    
    </body>
    </html>";
    

    enter image description here