Xamarin.Forms: MultiLineLabel no longer works on Android

In my Xamarin.Forms project, I use MultiLineLabel to display the title on 1 or 2 lines, depending on the length of the text. For this, I am based on this blog .

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 :

  • in iOS , I saved this 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 set up rendering:

     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:

screenshot before updating

But after upgrading to the latest version ( Xamarin.Forms v.2.4.0.269-pre2 ), it does not work as expected:

screenshot after update

I also tried using the renderer specified 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 did not get the expected rendering: screenshot after update - alternative

Do you have any explanation? Or another suggestion? On iOS, this works well.

+2
source share
1 answer

But after upgrading to the latest version (Xamarin.Forms v.2.4.0.269-pre2), it no longer works as expected:

Cause:

I checked the source code of Xamarin.Forms v.2.4.0.269-pre2 . In the LabelRenderer OnElementChange event, the LabelRenderer OnElementChange will be called, which contains the 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); will be called textView.SetMaxLines(1); and textView.SetSingleLine(true); that will disable the multi-line function. (In 2.3.4 textView.SetSingleLine(true); does not exist).

Decision:

To fix the problem, you just need to add two lines of codes to 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); } } 
+3
source

All Articles