【问题标题】:Xamarin.Forms: the MultiLineLabel doesn't longer work on AndroidXamarin.Forms:MultiLineLabel 不再适用于 Android
【发布时间】:2018-02-13 00:09:36
【问题描述】:

在我的 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 上运行良好。

【问题讨论】:

    标签: android xamarin.forms label multiline custom-renderer


    【解决方案1】:

    但在更新到最新版本(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.TailTruncationtextView.SetMaxLines(1);textView.SetSingleLine(true);会被调用,这会禁用多行功能。(在2.3.4textView.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); 行的情况下使用它,因为我希望标签根据内容自动扩展。
    猜你喜欢
    • 1970-01-01
    • 2015-01-22
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 2019-10-23
    • 2013-01-27
    相关资源
    最近更新 更多