Xamarin.Forms:MultiLineLabel 不再适用于 Android
Xamarin.Forms: the MultiLineLabel doesn't longer work on Android
在我的 Xamarin.Forms 项目中,我使用 MultiLineLabel 在 1 或 2 行上显示标题,具体取决于文本长度。我就是基于这个blog实现的
所以我有一个 MultiLineLabel
控件:
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); }
}
}
我使用 2 个 渲染器:
在 iOS,我保留了给定的渲染器:
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;
}
}
在 Android 我已经自定义了渲染器:
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);
}
}
}
我在 XAML:
中像这样使用 MultiLineLabel
<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>
在我使用 Xamarin.Forms v.2.3.4.247
之前,它在 Android:
上运行良好
但是在更新到最新版本(Xamarin.Forms v.2.4.0.269-pre2
)之后,它不再像预期的那样工作了:
我也试过使用博客上给出的渲染器:
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);
}
}
但是我没有得到预期的渲染:
有什么解释吗?或者另一个建议?在 iOS 上效果很好。
But after having updated to the latest version (Xamarin.Forms v.2.4.0.269-pre2), it doesn't longer work as expected:
原因:
我查看了Xamarin.Forms v.2.4.0.269-pre2
的源代码。在LabelRenderer
的OnElementChange
事件中,FormsTextView
的SetLineBreakMode
将被调用,其中包含以下代码:
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;
}
}
如你所见,如果你使用LineBreakMode.TailTruncation
,textView.SetMaxLines(1);
和textView.SetSingleLine(true);
将被调用,这将禁用多行功能。(在2.3.4
textView.SetSingleLine(true);
不存在)。
解法:
要解决这个问题,您只需在渲染器中添加两行代码:
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);
}
}
在我的 Xamarin.Forms 项目中,我使用 MultiLineLabel 在 1 或 2 行上显示标题,具体取决于文本长度。我就是基于这个blog实现的
所以我有一个 MultiLineLabel
控件:
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); }
}
}
我使用 2 个 渲染器:
在 iOS,我保留了给定的渲染器:
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; } }
在 Android 我已经自定义了渲染器:
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); } } }
我在 XAML:
中像这样使用 MultiLineLabel<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>
在我使用 Xamarin.Forms v.2.3.4.247
之前,它在 Android:
但是在更新到最新版本(Xamarin.Forms v.2.4.0.269-pre2
)之后,它不再像预期的那样工作了:
我也试过使用博客上给出的渲染器:
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);
}
}
但是我没有得到预期的渲染:
有什么解释吗?或者另一个建议?在 iOS 上效果很好。
But after having updated to the latest version (Xamarin.Forms v.2.4.0.269-pre2), it doesn't longer work as expected:
原因:
我查看了Xamarin.Forms v.2.4.0.269-pre2
的源代码。在LabelRenderer
的OnElementChange
事件中,FormsTextView
的SetLineBreakMode
将被调用,其中包含以下代码:
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;
}
}
如你所见,如果你使用LineBreakMode.TailTruncation
,textView.SetMaxLines(1);
和textView.SetSingleLine(true);
将被调用,这将禁用多行功能。(在2.3.4
textView.SetSingleLine(true);
不存在)。
解法:
要解决这个问题,您只需在渲染器中添加两行代码:
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);
}
}