Xamarin Forms Label - Justify?
Solution 1
Though you can't stretch label's text to a full width using Xamarin.Forms features, it's easily achieved with a platform renderer.
Most Xamarin platforms have the text justification feature available in corresponding native elements, and it's just a matter of setting a single attribute of a native element. I suppose the reason for not adding this feature to standard Xamarin.Forms label is lagging of platforms in that capability, e.g. Android had Android.Text.JustificationMode.InterWord flag added only in version 8.1
Below you can see Android renderer implementation:
using Android.Content;
using Saplin.CPDT.UICore.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Saplin.CPDT.UICore.Controls.ExtendedLabel), typeof(Saplin.CPDT.Droid.ExtnededLabelRenderer))]
namespace Saplin.CPDT.Droid
{
public class ExtnededLabelRenderer : Xamarin.Forms.Platform.Android.LabelRenderer
{
public ExtnededLabelRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var el = (Element as ExtendedLabel);
if (el != null && el.JustifyText)
{
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
Control.JustificationMode = Android.Text.JustificationMode.InterWord;
}
}
}
}
}
- Your create renderer class in native project
- You add assembly: ExportRenderer attribute
- You set TextView's JustificationMode
In my example I used ExtenedLabel subclass of Xamarin.Forms.Label with extra property JustifyText to let setting the justification of the text. That's how the subclassed control can be declared:
using System;
using Xamarin.Forms;
namespace Saplin.CPDT.UICore.Controls
{
public class ExtendedLabel : Label
{
public static readonly BindableProperty JustifyTextProperty =
BindableProperty.Create(
propertyName: nameof(JustifyText),
returnType: typeof(Boolean),
declaringType: typeof(ExtendedLabel),
defaultValue: false,
defaultBindingMode: BindingMode.OneWay
);
public bool JustifyText
{
get { return (Boolean)GetValue(JustifyTextProperty); }
set { SetValue(JustifyTextProperty, value); }
}
}
}
Solution 2
The current way to do this is by using HorizontalTextAlignment
and the values for the TextAlignment
enumeration are:
-
Center
= Center-aligned text -
Start
= Left-aligned -
End
= Right-aligned
Center a label and its text example:
<Label x:Name="Description" HorizontalTextAlignment="Center"
VerticalOptions="Center" HorizontalOptions="Center" />
Solution 3
Use the XAlign
property
Label lbl = new Label();
lbl.Text = "I'm a Label!";
lbl.XAlign = TextAligntment.Start; // Start, Center, End are valid
Solution 4
As it can't be done directly within a label, a workaround is to use the new FlexLayout
from Xamarin.Forms 3. The idea is to split the text at space character and insert corresponding label in the FlexLayout
with JustifyContent
set to SpaceBetween
.
Example :
XAML
<Frame
HorizontalOptions="Center"
Margin="20,50,20,0"
Padding="10"
WidthRequest="300"
HasShadow="true">
<FlexLayout
x:Name="TextContainer"
Direction="Row"
AlignItems="End"
JustifyContent="SpaceBetween"
Wrap="Wrap"/>
</Frame>
Code behind
var textparts = "This is a long text to be justified"
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Select(x => new Label
{
Text = x,
FontSize = 12,
TextColor = Color.FromHex("#555555"),
Margin = new Thickness(1, 0)
});
foreach (var textpart in textparts)
TextContainer.Children.Add(textpart);
ainer
Updated on July 09, 2022Comments
-
ainer almost 2 years
I just wanted to ask if there is any way to justify text in a Label. I am using Xamarin Forms Xaml.
Thanks.
UPDATE: As for now, it is not possible to justify text. Most of the answers were about centering the text, but it is not what I asked. One way could be to use Renderer as by Timothy.