繁体   English   中英

Xamarin.Forms:MultiLineLabel不再适用于Android

[英]Xamarin.Forms: the MultiLineLabel doesn't longer work on Android

在我的Xamarin.Forms项目中,我使用MultiLineLabel在1或2行显示标题,具体取决于文本长度。 我基于这个博客来实现这一目标。

所以我有一个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上这很好用。

但在更新到最新版本(Xamarin.Forms v.2.4.0.269-pre2)后,它不再按预期工作:

原因:

我查看了Xamarin.Forms v.2.4.0.269-pre2的源代码。 LabelRendererOnElementChange事件中,将调用FormsTextViewSetLineBreakMode ,其中包含以下代码:

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);

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM