Xamarin Forms 自定义字体 CrossPlatform

Xamarin Forms Custom Fonts CrossPlatform

我正在遵循 Xamarin 提出的 Fonts Tutorial 在每个平台上自定义下载字体。然而,我遇到了很多问题,我也试图找到一种方法来做一些事情,但没有找到如何让它工作。

首先,看一下教程,然后从相关部分开始。 Using a Custom Font


iOS:

它说我们必须将 font.tff 添加到 资源文件夹 中。 然后,我们必须对 Info.plist 做点什么,但是什么?我不确定我必须做什么。

Android:

Xamarin.Forms for Android 当前不公开将字体设置为自定义字体文件的功能,因此需要自定义渲染器。

CustomLabelRenderer.cs

public class CustomLabelRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        System.Diagnostics.Debug.WriteLine(Forms.Context.ApplicationContext.Assets, e.NewElement.StyleId + ".ttf");

        if (!string.IsNullOrEmpty(e.NewElement?.StyleId))
        {
            var font = Typeface.CreateFromAsset(Forms.Context.ApplicationContext.Assets, e.NewElement.StyleId + ".ttf");
            Control.Typeface = font;
        }
    }
}

根据文档,OnElementChanged() 会被调用,但实际上并没有。 Debug.WriteLine() 不显示任何内容。 为什么?

赢Phone 8.1:

我们必须将字体文件添加到应用程序项目中的 /Assets/Fonts/ 文件夹并设置 Build Action:Content。一旦实现,Xamarin.Forms for Windows Phone 可以引用已按照特定命名标准添加到项目中的自定义字体。 但是,字体不会出现在视图上,字体保持标准,为什么?


目前,经过大量的搜索,大量的尝试...没有..

我正在尝试添加 DIN Condensed Bold 字体

我的XAML布局:

<ContentPage.Content>
 <AbsoluteLayout BackgroundColor="#235A5E">
  <!-- Menu -->
  <AbsoluteLayout x:Name="Menu" BackgroundColor="#2F767B"
                  AbsoluteLayout.LayoutBounds="0,0,1,0.1"
                  AbsoluteLayout.LayoutFlags="All">
    <Label x:Name="label" Text="Connection" TextColor="White" FontSize="30" VerticalOptions="Center" HorizontalOptions="Center"
           AbsoluteLayout.LayoutBounds="0.5, 0, 0.8, 1"
           AbsoluteLayout.LayoutFlags="All"/>
    <Button x:Name="ConnectionButton" BackgroundColor="Transparent" BorderColor="Transparent"
           AbsoluteLayout.LayoutBounds="1, 0.5, 0.2, 1"
           AbsoluteLayout.LayoutFlags="All"/>
  </AbsoluteLayout>
 </AbsoluteLayout>
</ContentPage.Content>

所以Label的FontFamily属性可以这样设置

<Label Text="Hello World !" FontFamily="DIN Condensed Bold"

但是,如教程中所述,对于 WinPhone 示例,它必须通过其他方式完成,因此,我尝试通过 C# 部分更改 FontFamily。

public partial class MyPage : ContentPage
{
    public string FontFamily { get; set; }

    public MyPage()
    {
        InitializeComponent();

        label.FontFamily = Device.OnPlatform(
            iOS: "DIN Condensed Bold",
            Android: "DIN Condensed Bold",
            WinPhone: @"Assets\Fonts\DINCondensedBold.ttf#DIN Condensed Bold"
        );
    }
}

这也行不通!我还看到 XAML 部分对我来说很有趣。我希望(如果 FontFamily 有一天能工作......)有一个 defintion 我们让我能够只编辑一个字段字符串来设置我页面的所有标签的 FontFamily。

<ContentPage.Resources>
  <ResourceDictionary>

  </ResourceDictionary>
</ContentPage.Resources>

我看到我可以为 MyPage.xaml 的所有 Label 定义一个 FontFamily,它是如何工作的?

我也是 MVVM 的新手,但我尝试将我的 public string FontFamily { get; set; } 绑定到 xaml <Label Text="Hello World !" FontFamily="{Binding FontFamily}"/> 中定义的标签,但又一次没有成功..

我完全卡住了...谁可以帮助制作教程或解释我在教程后提到的每件事。感谢帮助!

我认为在某些时候,Xamarin Forms 方法比需要自定义渲染器(或效果器等)更容易。首先是官方指导:https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/fonts/#Using_a_Custom_Font.

iOS、Android 和 UWP 的工作解决方案,对我来说最终是这样的:

    <Label Text="The sly fox jumps over the lazy brown dog.">
        <Label.FontFamily>
            <OnPlatform x:TypeArguments="x:String">
                <On Platform="iOS" Value="OpenSans-Semibold"/>
                <On Platform="Android" Value="Fonts/OpenSans-Semibold.ttf#OpenSans-Semibold"/>
                <On Platform="UWP" Value="Assets\Fonts\OpenSans-Semibold.ttf#Open Sans"/>
            </OnPlatform>
        </Label.FontFamily>
    </Label>

对于所有三个平台,此示例中的字体文件都存储在 Fonts 子文件夹中。您会在上面的 Android 和 UWP (WinPhone) 路径中看到这一点。在 iOS 中,plist 条目包含自定义字体的路径信息。

最难的部分是确定字体名称/首选字体。请注意 Android 和 UWP/WinPhone 的“#”后的差异。反复试验 (Android) 并感谢这篇文章帮助指出所需的特异性:http://www.blendrocks.com/code-blend/2015/01/04/a-complete-guide-to-working-with-custom-fonts-in-your-windows-and-windows-phone-app.

该文章最相关的部分是首选字体名称的挑剔程度和不明显程度。 Windows 字体查看器(还有 Mac 字体书,顺便说一句,afaik)不会向您显示首选的姓氏。来自文章:

This part "#Helvetica Neue LT Std" is a suffix containing the Preferred Family. It's required in order for the custom font to work. The suffix has to be absolutely correct and it's case sensitive.

  • The easiest way to find it is to use a tool called dp4 font viewer. It's free and can be found downloaded here. Find your font through the program, go to the info tap copy the Preferred Family.
  • Do NOT use Windows built in font viewer as it does NOT show the correct preferred font family.

编辑:将 OnPlatform 片段更新为当前推荐的语法。

EDIT2:将 WinPhone 平台更改为 UWP 并删除了 UWP 路径的前导反斜杠“\”——没有意识到这在 UWP/WinPhone 上不起作用!还修复了 dp4 字体查看器的下载 link,因为它现在需要 'https'。

2020 更新,Xamarin.Forms 4.5 支持在一个地方嵌入自定义字体(共享 UI 项目)并通过 ExportFont 属性导出:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/fonts#use-a-custom-font - 适用于 iOS, Android 和 UWP。对于 macOS 和 WPF,您仍然必须按如下所述在每个平台项目中嵌入字体。

  1. 下载 TTF 文件并将它们作为资源与每个平台项目捆绑
  2. 参考 Xamarin.Forms 共享项目中的字体,同时考虑到每个平台的特性(寻址资源和字体系列的命名约定)。
  3. 将字体应用于 Xamarin.Forms 控件。

Here's detailed description 关于如何在 macOS、WPF 和 Android.

中添加和应用自定义字体

从 Xamarin.Forms 4.5.530 及更高版本开始,无需指定平台,也无需向每个原生项目(Android、iOS 和 UWP)添加字体文件。强烈推荐 Xamarin devblogs 文章作为指南。

我的做法:添加一个自定义字体文件,fx。 OpenSans-Regular.ttf,到共享代码项目中的一个新文件夹。将 [assembly: ExportFont("OpenSans-Regular.ttf", Alias = "OpenSans")] 和命名空间引用 using Xamarin.Forms; 添加到共享代码项目中的 AssemblyInfo.cs 文件。然后从 .xaml 文件中的控件引用别名,如下所示 <Label Text="Username" FontFamily="OpenSans" />