On my Xamarin.Forms project, I use a MultiLineLabel to display a title on 1 or 2 lines, depending the text length. I'm based on this blog to achieve this.
So I have a MultiLineLabel
control:
public class MultiLineLabel : Label
{
private static int _defaultLineSetting = -1;
public static readonly BindableProperty LinesProperty = BindableProperty.Create(nameof(Lines), typeof(int), typeof(MultiLineLabel), _defaultLineSetting);
public int Lines
{
get { return (int)GetValue(LinesProperty); }
set { SetValue(LinesProperty, value); }
}
}
I use 2 renderers:
on iOS, I've kept the given renderer:
public class CustomMultiLineLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
MultiLineLabel multiLineLabel = (MultiLineLabel)Element;
if (multiLineLabel != null && multiLineLabel.Lines != -1)
Control.Lines = multiLineLabel.Lines;
}
}
on Android I've customized the renderer:
public class CustomMultiLineLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
MultiLineLabel multiLineLabel = (MultiLineLabel)Element;
if (multiLineLabel != null && multiLineLabel.Lines != -1)
{
Control.Ellipsize = TextUtils.TruncateAt.End;
Control.SetMaxLines(multiLineLabel.Lines);
}
}
}
And I use this MultiLineLabel like this in XAML:
<StackLayout
Grid.Row="0"
Spacing="0">
<local:MultiLineLabel
Margin="8,6,8,0"
TextColor="{ DynamicResource InverseTextColor }"
Text="{ Binding encart_titre }"
FontSize="{ artina:OnOrientationDouble
Default=16,
PortraitTablet=20,
LandscapeTablet=20 }"
LineBreakMode="TailTruncation"
Lines="2"
Grid.Column="0"
BackgroundColor="Yellow"
/>
</StackLayout>
Until I used Xamarin.Forms v.2.3.4.247
, this worked well on Android:
But after having updated to the latest version (Xamarin.Forms v.2.4.0.269-pre2
), it doesn't longer work as expected:
I also tried to use the renderer given on the blog:
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
MultiLineLabel multiLineLabel = (MultiLineLabel)Element;
if (multiLineLabel != null && multiLineLabel.Lines != -1)
{
Control.SetSingleLine(false);
Control.SetLines(multiLineLabel.Lines);
}
}
But I didn't get the expected rendering:
Would you have any explanation? Or another suggestion? On iOS this works well.
Not dead but possibly moribund. In May 2020, Microsoft announced that Xamarin. Forms, a major component of its mobile app development framework, would be deprecated in November 2021 in favour of a new . Net based product called MAUI - Multiform App User Interface.
Generally, the main distinction between the two platforms is that Xamarin. Forms allows reusing the same UI code for multiple OS, whereas Xamarin Native is adapted to APIs, specific to a specific platform – Windows, iOS, Android.
Xamarin. Android applications compile from C# into Intermediate Language (IL) which is then Just-in-Time (JIT) compiled to a native assembly when the application launches. Xamarin. Android applications run within the Mono execution environment, side by side with the Android Runtime (ART) virtual machine.
If you have a text that is to large to fit the width of your label, you can use the attribute called LineBreakMode=TailTruncation. This will display a text with “…” at the end (ellipsis) when the text doesn't fit. Let's take for example this text: “Welcome to Xamarin Forms” inside a Label like in the exmple below: <?
But after having updated to the latest version (Xamarin.Forms v.2.4.0.269-pre2), it doesn't longer work as expected:
Cause:
I've checked the source codes of Xamarin.Forms v.2.4.0.269-pre2
. In LabelRenderer
's OnElementChange
event, FormsTextView
's SetLineBreakMode
will be called which contains following codes:
public static void SetLineBreakMode(this TextView textView, LineBreakMode lineBreakMode)
{
switch (lineBreakMode)
{
case LineBreakMode.NoWrap:
textView.SetMaxLines(1);
textView.SetSingleLine(true);
textView.Ellipsize = null;
break;
case LineBreakMode.WordWrap:
textView.Ellipsize = null;
textView.SetMaxLines(100);
textView.SetSingleLine(false);
break;
case LineBreakMode.CharacterWrap:
textView.Ellipsize = null;
textView.SetMaxLines(100);
textView.SetSingleLine(false);
break;
case LineBreakMode.HeadTruncation:
textView.SetMaxLines(1);
textView.SetSingleLine(true);
textView.Ellipsize = TextUtils.TruncateAt.Start;
break;
case LineBreakMode.TailTruncation:
textView.SetMaxLines(1);
textView.SetSingleLine(true);
textView.Ellipsize = TextUtils.TruncateAt.End;
break;
case LineBreakMode.MiddleTruncation:
textView.SetMaxLines(1);
textView.SetSingleLine(true);
textView.Ellipsize = TextUtils.TruncateAt.Middle;
break;
}
}
As you can see, if you use LineBreakMode.TailTruncation
, textView.SetMaxLines(1);
and textView.SetSingleLine(true);
will be called, which disable the multi line function.(In 2.3.4
textView.SetSingleLine(true);
doesn't exist).
Solution:
To fix the problem, you simply need to add two lines of codes in your renderer:
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Label> e)
{
base.OnElementChanged(e);
MultiLineLabel multiLineLabel = (MultiLineLabel)Element;
if (multiLineLabel != null && multiLineLabel.Lines != -1)
{
Control.SetSingleLine(false);
Control.SetMaxLines(multiLineLabel.Lines);
Control.SetLines(multiLineLabel.Lines);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With