訪問 Syles 中的自定義字型

Xamarin.Forms 為使用全域性樣式設計跨平臺應用程式提供了很好的機制。

在移動世界中,你的應用程式必須漂亮並且能夠從其他應用程式中脫穎而其中一個字元是應用程式中使用的自定義字型。

在 Xamarin.Forms 中使用 XAML Styling 的強大支援,只需為你的自定義字型建立所有標籤的基本樣式。

要在 iOS 和 Android 專案中包含自定義字型,請遵循使用由 Gerald 編寫的 Xamarin.Forms帖子在 iOS 和 Android 上使用自定義字型的指南。

在 App.xaml 檔案資源部分中宣告樣式。這使得所有樣式全域性可見。

從上面的 Gerald 帖子我們需要使用 StyleId 屬性,但它不是可繫結屬性,所以要在 Style Setter 中使用它,我們需要為它建立 Attachable 屬性:

public static class FontHelper
{
    public static readonly BindableProperty StyleIdProperty =
        BindableProperty.CreateAttached(
            propertyName: nameof(Label.StyleId),
            returnType: typeof(String),
            declaringType: typeof(FontHelper),
            defaultValue: default(String),
            propertyChanged: OnItemTappedChanged);

    public static String GetStyleId(BindableObject bindable) => (String)bindable.GetValue(StyleIdProperty);

    public static void SetStyleId(BindableObject bindable, String value) => bindable.SetValue(StyleIdProperty, value);

    public static void OnItemTappedChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = bindable as Element;
        if (control != null)
        {
            control.StyleId = GetStyleId(control);
        }
    }
}

然後在 App.xaml 資源中新增樣式:

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:h="clr-namespace:My.Helpers"
             x:Class="My.App">

  <Application.Resources>

    <ResourceDictionary>
        <Style x:Key="LabelStyle" TargetType="Label">
            <Setter Property="FontFamily" Value="Metric Bold" />
            <Setter Property="h:FontHelper.StyleId" Value="Metric-Bold" />
        </Style>
    </ResourceDictionary>

  </Application.Resources>

</Application>

根據上面的帖子,我們需要建立 Label 的 Custom Renderer,它繼承自 Android 平臺上的 LabelRenderer。

internal class LabelExRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);
        if (!String.IsNullOrEmpty(e.NewElement?.StyleId))
        {
            var font = Typeface.CreateFromAsset(Forms.Context.ApplicationContext.Assets, e.NewElement.StyleId + ".ttf");
            Control.Typeface = font;
        }
    }
}

對於 iOS 平臺,不需要自定義渲染器。

現在,你可以在頁面標記中獲取樣式:

對於特定標籤

<Label Text="Some text" Style={StaticResource LabelStyle} />

或者通過建立基於 LabesStyle 的樣式將樣式應用於頁面上的所有標籤

<!-- language: xaml -->

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="My.MainPage">

  <ContentPage.Resources>

    <ResourceDictionary>
        <Style TargetType="Label" BasedOn={StaticResource LabelStyle}>
        </Style>
    </ResourceDictionary>

  </ContentPage.Resources>

  <Label Text="Some text" />      

</ContentPage>