2017/2/13

Xamarin.Forms 教學系列文(三.貳)文字屬性 & 格式化



接續上一節繼續玩弄文字...

學習目標
  • Label 屬性設定
  • Label 內文字分段設定屬性

Label,其文字大小或字型,通常預設是各個平台的預設值,不過 Label 也定義了一些屬性,讓開發者可以客製化。

Label 有三種屬性可以更改:
  • FontFamily of type string
  • FontSize of type double
  • FontAttributes of type FontAttributes, 有三個成員可以使用:None, Bold, Italic


FontFamily 是最難用的,理論上你要設定字型只要將值設定為 "Times Roman" 之類的描述字串就能更改字型,但你還要確認:
  1. 平台是否支援此字型
  2. 此字型在此平台上被稱做什麼

FontSize 跟手機的 大小單位 有關係,關於 單位 在第五章有更詳細的討論。

在這裡,Xamarin.Forms Device 提供靜態方法 GetNamedSize 讓我們更方便的去設定字型大小,方法需要帶入 NameSize 參數,而 NameSize 包含的物件成員如下:
  1. Default
  2. Micro
  3. Small
  4. Medium
  5. Large
GetNamedSize 還需帶入物件的類別,像是 typeof(Label) 或是 typeof(Button)。

FontAttributes 是這三個最容易使用的屬性,可以帶入 Bold 或是 Italic。

來看一下程式碼:
    class GreetingsPage : ContentPage
    {
        public GreetingsPage()
        {
            Content = new Label
            {
                Text = "Greetings, Xamarin.Forms!",
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                FontAttributes = FontAttributes.Bold | FontAttributes.Italic
            };
        }
    }

三個平台的執行結果如下:


文字格式化

Label 除了 Text 可以設定文字外,也提供了一個 FormattedText 屬性讓開發者分段設定文字和其屬性。

白話一點就是,如果同一段文字內每個句子的屬性都要不一樣,就能用 FormattedText 分別處理。

FormattedText 的類別為 FormattedString,而 FormattedString 提供 Spans 屬性可以使用,其類別為 IList<Span>,每個 Span 底下有六種屬性可以設定:

  • Text
  • FontFamily
  • FontSize
  • FontAttributes
  • ForegroundColor
  • BackgroundColor

直接看程式碼:
    public class VariableFormattedTextPage : ContentPage
    {
        public VariableFormattedTextPage()
        {
            FormattedString formattedString = new FormattedString();
            formattedString.Spans.Add(new Span
            {
                Text = "I "
            });

            formattedString.Spans.Add(new Span
            {
                Text = "love",
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                FontAttributes = FontAttributes.Bold
            });

            formattedString.Spans.Add(new Span
            {
                Text = " Xamarin.Forms!"
            });

            Content = new Label
            {
                FormattedText = formattedString,
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
            };
        }
    }

上方是建構子的方式,宣告每個 Span 和其屬性後加入 FromattedString 內,
不過,也可以直接在 Label 內初始化 FormattedText :
        public VariableFormattedTextPage()
        {
            Content = new Label
            {
                FormattedText = new FormattedString
                {
                    Spans =
                    {
                        new Span
                        {
                            Text = "I "
                        },
                        new Span
                        {
                            Text = "love",
                            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                            FontAttributes = FontAttributes.Bold
                        },
                        new Span
                        {
                            Text = " Xamarin.Forms!"
                        }
                    }
                },
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
            };
        }
執行結果如下

可以新增值為 NewLine 的 Span 來換行

下方程式碼是用迴圈將每一個字體大小顯示出來,並在每個 Span 之間加入換行:
    public class NamedFontSizesPage : ContentPage
    {
        public NamedFontSizesPage()
        {
            FormattedString formattedString = new FormattedString();
            NamedSize[] namedSizes = 
            {
                NamedSize.Default,
                NamedSize.Micro,
                NamedSize.Small,
                NamedSize.Medium,
                NamedSize.Large
            };

            foreach (NamedSize namedSize in namedSizes)
            {
                double fontSize = Device.GetNamedSize(namedSize, typeof(Label));
                formattedString.Spans.Add(new Span
                {
                    Text = String.Format("Named Size = {0} ({1:F2})", 
                    namedSize,
                    fontSize),
                    FontSize = fontSize
                });

                if (namedSize != namedSizes.Last())
                {
                    formattedString.Spans.Add(new Span
                    {
                        Text = Environment.NewLine + Environment.NewLine
                    });
                }
            }

            Content = new Label
            {
                FormattedText = formattedString,
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center
            };
        }
    }

執行結果如下:

不過,在 Label 內顯示一個段落的文字,用 Span 每個拆開並不是很好的方法... 更多的情況下段落都很長的..長到需要上下捲動...

下一章節會來探討 StackLayout 和 ScrollView 如何讓多行的文字在手機上捲動。




沒有留言:

張貼留言