问题
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.
回答1:
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);
}
}
来源:https://stackoverflow.com/questions/46042386/xamarin-forms-the-multilinelabel-doesnt-longer-work-on-android