有什么办法可以使标签从左到右填充整个空间? [英] Is there any way to make a label fill the space from left to right?

查看:77
本文介绍了有什么办法可以使标签从左到右填充整个空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

<StackLayout>
   <Label x:Name="emptyLabel1" FontSize="18" XAlign="Start" TextColor="Gray" />
   <Label x:Name="emptyLabel2" FontSize="18" XAlign="Center" TextColor="Gray" />
   <Label x:Name="emptyLabel3" FontSize="18" XAlign="Center" TextColor="Gray" />
</StackLayout>

第一个多行标签从左侧开始,但在右侧的某些行上有空格.第二和第三条多行标签居中,并且左右两边都有空格.

The first multi-line label starts on the left but has spaces on some of the rows on the right. The 2nd and 3rd multi-line labels are centered and have spaces on both left and right.

有没有办法让标签的所有行完全填满,行从左到右完全填满o每行的第一个字符始终在左边排成一行,而每行的最后一个单词的最后一个字符始终排成一行行总是在右边排成一行?注意,这将要求每行中的某些单词之间具有不同的间隔.

Is there any way that I can have all rows of the labels completely fill the rows completely fill from left to right o that the first character of each row always lines up on the left and the last character of the last word of each row always lines up on the right? Note that this would require some words in each line to have different gaps between them.

推荐答案

使用对齐对齐支持实现标签有点棘手,但是可以通过平台渲染器来实现.

It is a bit tricky to implement label with justify alignment support, but it is possible through platform renderer(s).

第一步是在Forms项目中声明一个自定义控件.

First step would be to declare a custom control in forms project.

public class JustifiedLabel : Label { }

下一步是在iOS中定义和注册平台渲染器.这很简单,因为我们只需将格式字符串与段落样式结合起来即可得到我们想要的东西.

Next step is to define and register the platform renderer in iOS. This one is simple, as we simply combine formatted-string with paragraph-style to get what we want.

[assembly: ExportRenderer(typeof(JustifiedLabel), typeof(JustifiedLabelRenderer))]
namespace SomeAppNamespace.iOS
{   
    public class JustifiedLabelRenderer : 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(Label.Text) 
               || e.PropertyName == nameof(Label.FontFamily) 
               || e.PropertyName == nameof(Label.FontSize)
               || e.PropertyName == nameof(Label.TextColor)
               || e.PropertyName == nameof(Label.FontAttributes))
            {
                UpdateTextOnControl();
            }
        }

        void UpdateTextOnControl()
        {
            if (Control == null)
                return;

            //define paragraph-style
            var style = new NSMutableParagraphStyle()
            {
                Alignment = UITextAlignment.Justified,
                FirstLineHeadIndent = 0.001f,
            };

            //define attributes that use both paragraph-style, and font-style 
            var uiAttr = new UIStringAttributes()
            {
                ParagraphStyle = style,
                BaselineOffset = 0,

                Font = Control.Font
            };

            //define frame to ensure justify alignment is applied
            Control.Frame = new RectangleF(0, 0, (float)Element.Width, (float)Element.Height);

            //set new text with ui-style-attributes to native control (UILabel)
            var stringToJustify = Control.Text ?? string.Empty;
            var attributedString = new Foundation.NSAttributedString(stringToJustify, uiAttr.Dictionary);
            Control.AttributedText = attributedString;
            Control.Lines = 0;
        }
    }
}

在android平台中,这有点棘手-因为android不支持TextView的对齐对齐-因此我们将需要使用WebView代替它来呈现文本.

In android platform, it is a bit trickier - as android doesn't support justify alignment for TextView - so we will need to use a WebView instead to get it to render the text.

(注意:,您也可以或者使用android库并使用它代替WebView)

(Note: You can also alternatively use an android library and use it instead of WebView)

[assembly: ExportRenderer(typeof(JustifiedLabel), typeof(JustifiedLabelRenderer))]
namespace SomeAppNamespace.Droid
{
    //We don't extend from LabelRenderer on purpose as we want to set 
    // our own native control (which is not TextView)
    public class JustifiedLabelRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<View> 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)
            {
                if (Control == null)
                {
                    //register webview as native control
                    var webView = new Android.Webkit.WebView(Context);
                    webView.VerticalScrollBarEnabled = false;
                    webView.HorizontalScrollBarEnabled = false;

                    webView.LoadData("<html><body>&nbsp;</body></html>", "text/html; charset=utf-8", "utf-8");
                    SetNativeControl(webView);
                }

                //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
                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(Label.Text)
               || e.PropertyName == nameof(Label.FontFamily)
               || e.PropertyName == nameof(Label.FontSize)
               || e.PropertyName == nameof(Label.TextColor)
               || e.PropertyName == nameof(Label.FontAttributes))
            {
                UpdateTextOnControl();
            }
        }

        void UpdateTextOnControl()
        {
            var webView = Control as Android.Webkit.WebView; 
            var formsLabel = Element as Label;

            // create css style from font-style as specified
            var cssStyle = $"margin: 0px; padding: 0px; text-align: justify; color: {ToHexColor(formsLabel.TextColor)}; background-color: {ToHexColor(formsLabel.BackgroundColor)}; font-family: {formsLabel.FontFamily}; font-size: {formsLabel.FontSize}; font-weight: {formsLabel.FontAttributes}";

            // apply that to text 
            var strData =
                $"<html><body style=\"{cssStyle}\">{formsLabel?.Text}</body></html>";

            // and, refresh webview
            webView.LoadData(strData, "text/html; charset=utf-8", "utf-8");
            webView.Reload();
        }

        // helper method to convert forms-color to css-color
        string ToHexColor(Color color)
        {
            var red = (int)(color.R * 255);
            var green = (int)(color.G * 255);
            var blue = (int)(color.B * 255);
            var alpha = (int)(color.A * 255);
            var hex = $"#{red:X2}{green:X2}{blue:X2}";

            return hex;
        }
    }
}

样品用量

<StackLayout Margin="20">
    <Entry x:Name="InputEntry" />

    <Label Margin="0,10,0,0" BackgroundColor="Navy" TextColor="White" Text="Normal Text Label" FontSize="15" HorizontalOptions="CenterAndExpand" />
    <Label 
            FontSize="20" 
            FontAttributes="Bold"  
            Text="{Binding Text, Source={x:Reference InputEntry}}" />

    <Label Margin="0,10,0,0" BackgroundColor="Navy" TextColor="White" Text="Justified Text Label" FontSize="15" HorizontalOptions="CenterAndExpand" />
    <local:JustifiedLabel 
            FontSize="20" 
            FontAttributes="Bold" 
            Text="{Binding Text, Source={x:Reference InputEntry}}"
            TextColor="Green"
            BackgroundColor="Yellow"
            VerticalOptions="FillAndExpand"
            HorizontalOptions="FillAndExpand" />

</StackLayout>

这篇关于有什么办法可以使标签从左到右填充整个空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆