2017/8/3

Xamarin.Forms LineSpacingLabel - 可調整行距的 Label



剛好有人問,稍微研究一下及做個整理

問題就是:
如何增加 Label 內的文字行距 ( Xamarin.Forms 並沒有提供這屬性啊 ...

但仔細一看,其實 Android 和 iOS 都有提供行距的屬性可以設定... (看來只是 Xamarin.Forms 不想提供給我們用啊...

所以,目前的做法就是自行 客製化 一個附有 行距屬性 的 Label  (客製化教學在後面的章節...

讓我們姑且叫他 LineSpacingLabel


要客製化 LineSpacingLabel 有三個步驟

一、PCL 新增 LineSpacingLabel 

一個繼承於 Label 的類別,並給予一個全新的 double 屬性 - LineSpacing



using Xamarin.Forms;

namespace LineSpacingProject.Renders
{
    public class LineSpacingLabel : Label
    {
        public double LineSpacing { get; set; }
    }
}


二、Android 新增 LineSpacingLabelRenderer

主要目的就是,藉由 Android 客製化後,對應到 PCL 剛剛建立的 LineSpacingLabel 類別上
程式碼第 6 行








using LineSpacingProject.Renders;
using LineSpacingProject.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(LineSpacingLabel), typeof(LineSpacingLabelRenderer))]
namespace LineSpacingProject.Droid
{
    class LineSpacingLabelRenderer : LabelRenderer
    {
        protected LineSpacingLabel LineSpacingLabel { get; private set; }

        protected override void OnElementChanged(ElementChangedEventArgs

* 如果有遇到 using 一直引用不到 PCL 的狀況,試著做以下步驟來排除障礙
  1. 清除專案並重建
  2. Android 移除 PCL 參考再重新引用
  3. 重開 Visual Studio...
  4. 重開電腦...

三、回到 XAML 開心使用
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:LineSpacingProject.Renders"
             x:Class="LineSpacingProject.MainPage">

    <StackLayout>
        <local:LineSpacingLabel LineSpacing="5" 
                                Text="Welcome to Xamarin Forms!Welcome to Xamarin Forms!Welcome to Xamarin Forms!Welcome to Xamarin Forms!" />
    </StackLayout>

</ContentPage>

間距設定 5 的結果:


也可以設定 0.5 之類...


最後附上 iOS 客製化的部分:
            var lineSpacingLabel = (LineSpacingLabel)this.Element;
            var paragraphStyle = new NSMutableParagraphStyle()
            {
                LineSpacing = (nfloat)lineSpacingLabel.LineSpacing
            };
            var string = new NSMutableAttributedString(lineSpacingLabel.Text);
            var style = UIStringAttributeKey.ParagraphStyle;
            var range = new NSRange(0, string.Length);

            attrString.AddAttribute(style, paragraphStyle, range);

            this.Control.AttributedText = string;




10 則留言:

  1. 这个必须赞赞赞。我一直想找文字上下间距的资料。终于大神你发帖了。32个赞

    回覆刪除
    回覆
    1. 有機會大家一起討論和交流!

      刪除
    2. 罗大神,你平时有用什么即时通讯的软件吗?

      刪除
    3. 都用line比較多,可以加我ID:magic0800

      刪除
  2. 大神,protected override void OnElementChanged(ElementChangedEventArgs e),我使用OnElementChanged提示“没有找到合适的方法来重写”。请大神指点。

    回覆刪除
    回覆
    1. using 的部分都有引用上了嗎? 如果有繼承到 : LabelRenderer 這類別的話,照理說就能夠 override OnElementChanged 這方法了...

      刪除
    2. 找到问题的根本了,protected override void OnElementChanged(ElementChangedEventArgs e),ElementChangedEventArgs是一个泛型。需要指定参数。protected override void OnElementChanged(ElementChangedEventArgs Label e)就可以了

      刪除
  3. 还有一个小问题,在你的文档中,“一、PCL 新增 LineSpacingLabel ”截图中的".cs"文件的命名与你内容中的命名不一致,截图中“LinSpacingLabel.cs”,文档中使用的是“LineSpacingLabel”。

    回覆刪除
    回覆
    1. 阿阿抱歉沒注意到,已經修正截圖檔名,感謝提醒

      刪除