Xamarin Forms标签中的HTML

3

我正在使用Xamarin Forms为我的网站制作移动应用程序。在数据库中,我有一个包含一些html的字段。

我正在使用https://github.com/matteobortolazzo/HtmlLabelPlugin,但我似乎无法为我的html设置样式。

这是我的代码:

    public string Body { get; set; }

    public string BodyStyled => $"<!DOCTYPE html><html>" +
                                    $"<head>" +
                                        $"<style>" +
                                            $"p {{margin-bottom: 5px;}}" +
                                        $"</style>" +
                                    $"</head>" +
                                    $"<body>" +
                                        $"{Body}" +
                                    $"</body>" +
                                $"</html>";

                <htmlLabel:HtmlLabel
                    Grid.Row="0"
                    VerticalOptions="Center"
                    TextColor="{ DynamicResource BaseTextColor }"
                    Text="{ Binding Detail.BodyStyled }"/>

HTML会被执行,但p {margin-bottom: 5px;}会被打印在文本上方。

我该如何解决?谢谢!


这似乎是Xamarin Forms的一个bug。在我的情况下,iOS版本可以正常工作,但Android也会在HTML上方显示样式表内容。 - Frank
2个回答

6

2
你可以尝试这个方法: 1. 在你的PCL项目中创建自定义控件:
using Xamarin.Forms;

 namespace XYZ.CustomControl
  {
   //convert label text from HTML to simple display form
   public class CustomLabel: Label
    {
    }
  }

2. Android 渲染器:


using Android.Text;
using Android.Widget;
using XYZ.CustomControl;
using XYZ.Droid.Renderer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomLabel), typeof(HtmlFormattedLabelRenderer))]
namespace XYZ.Droid.Renderer
{
public class HtmlFormattedLabelRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        var view = (CustomLabel)Element;
        if (view == null) return;
        if (!string.IsNullOrEmpty(Control.Text))
        {
            if (Control.Text.Contains("<a"))
            {
                var a = Control.Text.IndexOf("<a");
                var b = Control.Text.IndexOf("</a>");
                var d = Control.Text.Length;
                var c = Control.Text.Length - Control.Text.IndexOf("</a>");
                int length = b - a+4;

                string code = Control.Text.Substring(a , length);
                Control.SetText(Html.FromHtml(view.Text.ToString().Replace(code,string.Empty)), TextView.BufferType.Spannable);
            }
            else
                Control.SetText(Html.FromHtml(view.Text.ToString()), TextView.BufferType.Spannable);
        }
    }
   }
}
  1. iOS renderer

     using Foundation;
     using XYZ.CustomControl;
     using XYZ.iOS.Renderer;
     using UIKit;
     using Xamarin.Forms;
     using Xamarin.Forms.Platform.iOS;
      [assembly: ExportRenderer(typeof(CustomLabel), 
    typeof(HtmlFormattedLabelRendereriOS))]
    namespace XYZ.iOS.Renderer
    {
         public class HtmlFormattedLabelRendereriOS:LabelRenderer
      {
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);
    
        var view = (CustomLabel)Element;
        if (view == null) return;
    
        var attr = new NSAttributedStringDocumentAttributes();
        var nsError = new NSError();
        attr.DocumentType = NSDocumentType.HTML;
    
        Control.AttributedText = new NSAttributedString(view.Text, attr, ref nsError);
    
        var mutable = Control.AttributedText as NSMutableAttributedString;
        UIStringAttributes uiString = new UIStringAttributes();
        uiString.Font = UIFont.FromName("Roboto-Regular",15f);
        uiString.ForegroundColor = UIColor.FromRGB(130, 130, 130);
    
        if (!string.IsNullOrEmpty(Control.Text))
        {
            if (Control.Text.Contains("<a"))
            {
                var text1 = Control.Text.IndexOf("<a");
                var text2 = Control.Text.IndexOf("</a>");
                int length = text2 - text1 + 4;
    
                string code = Control.Text.Substring(text1, length);
                Control.Text = Control.Text.Replace(code, string.Empty);                   
            }
        }
    
        mutable.SetAttributes(uiString, new NSRange(0, Control.Text.Length));
    
    }
     }
       }
    
希望这能帮助你解决问题。最初的回答:

希望这对你有所帮助。


这似乎可以工作,除了<a>标签。同时,我在这段代码Html.FromHtml上得到“已过时,不赞成使用”的警告提示。 - Nanou Ponette
你是否也有一个带有BindableProperty的解决方案? - Nanou Ponette
我现在没有,但是您可以在自定义控件中创建可绑定属性并使用它。 - MShah
@NanouPonette,针对iOS应该可以工作,虽然我没有测试过。在渲染器中使用GetSizeUsingAttributes方法,以测量字符串的宽度。 - MShah
或者你可以使用换行模式在标签上设置最大行数。 - MShah
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接