Voici le code que j'ai:
<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>
La première étiquette multiligne commence à gauche mais comporte des espaces sur certaines des lignes à droite. Les deuxième et troisième étiquettes multilignes sont centrées et comportent des espaces à gauche et à droite.
Est-il possible que toutes les lignes des étiquettes remplissent complètement les lignes de gauche à droite o que le premier caractère de chaque ligne est toujours aligné à gauche et que le dernier caractère du dernier mot de chaque ligne contient toujours des lignes sur la droite? Notez que cela nécessiterait que quelques mots dans chaque ligne aient des espaces différents entre eux.
Il est un peu délicat d’implémenter une étiquette avec un support d’alignement justifié, mais cela est possible grâce au rendu de la plate-forme.
La première étape serait de déclarer un contrôle personnalisé dans un projet de formulaires.
public class JustifiedLabel : Label { }
L'étape suivante consiste à définir et à enregistrer le rendu de la plateforme dans iOS. Celui-ci est simple, nous combinons simplement une chaîne formatée avec un style de paragraphe pour obtenir ce que nous voulons.
[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;
}
}
}
Sur la plate-forme Android, c'est un peu plus compliqué - car Android ne prend pas en charge l'alignement de TextView
-, nous devrons donc utiliser une WebView
à la place pour que le texte soit restitué.
(Remarque: Vous pouvez également utiliser alternativement une bibliothèque Android et l’utiliser à la place de 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> </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>
Je n'ai jamais vu de solution simple à cela, seulement des solutions de contournement comme mentionné ici .
Vous devez utiliser un composant ou créer votre propre solution pour chaque plate-forme.