Xamarin.Forms:多行标签在Android上不再起作用。

5
在我的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个渲染器

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

我在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);
    }
}

但是我没有得到预期的渲染效果:

updater后的截图 - 另一种选择

你有什么解释吗?或者还有其他建议吗?在iOS上这个效果很好。

1个回答

5
但是,自从更新到最新版本(Xamarin.Forms v.2.4.0.269-pre2)后,它不再像预期那样工作:
原因: 我已经检查了 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);

    }
}

嗨@Elvis Xia,感谢您的反馈。我没有使用Control.SetLines(multiLineLabel.Lines);这行代码,因为我希望标签根据内容自动扩展。 - Gold.strike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接