Xamarin Forms 自定义字体 CrossPlatform

Posted

技术标签:

【中文标题】Xamarin Forms 自定义字体 CrossPlatform【英文标题】:Xamarin Forms Custom Fonts CrossPlatform 【发布时间】:2016-10-14 09:09:01 【问题描述】:

我正在关注 Xamarin 建议的Fonts Tutorial,以便在每个平台上都有一个自定义下载字体。但是,我遇到了很多问题,我也尝试找到一种方法来做一些事情,但没有找到如何让它发挥作用。

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


ios

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

安卓:

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() 不显示任何内容。 为什么?

WinPhone 8.1:

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


目前,经过大量搜索,大量尝试......什么都没有......

我正在尝试添加 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属性可以这样设置

&lt;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 部分的一些有趣的东西。我希望(f FontFamily 有一天可以工作......)有一个defintion,我们让我能够只编辑一个字段字符串来设置我页面的所有 Label 的 FontFamily。

<ContentPage.Resources>
  <ResourceDictionary>

  </ResourceDictionary>
</ContentPage.Resources>

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

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

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

【问题讨论】:

阅读该指南链接的博客条目,它对修改 info.plist 有更详细的描述 您也可以尝试一次解决这个平台 - 因为您将多个问题打包到一个帖子中,很难简明扼要地回答 感谢您的回答。好的,对于其他人(Android/WinPhone)为什么它不起作用?我只想为遇到相同问题的人提出一个有用的问题/答案 我也遇到过类似的问题,请仔细检查文件名和字体名称是否相同,字体名称是否区分大小写。 谢谢 ;) 现在它适用于 Android,但不适用于 WinPhone 8.1... 【参考方案1】:

我认为在某些时候,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 Font Book,顺便说一句,afaik)不会向您显示首选的姓氏。来自文章:

这部分“#Helvetica Neue LT Std”是一个后缀,包含 首选家庭。它是自定义字体工作所必需的。 后缀必须绝对正确并且区分大小写。

找到它的最简单方法是使用名为 dp4 字体查看器的工具。它是免费的,可以在downloaded here 找到。找到你的字体 通过该程序,转到信息点击复制首选家庭。 不要使用 Windows 内置的字体查看器,因为它不会显示正确的首选字体系列。

编辑:将 OnPlatform sn-p 更新为当前推荐的语法。

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

【讨论】:

【参考方案2】:

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,您仍然需要在每个平台项目中嵌入字体,如下所述。

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

Here's detailed description 了解如何在 macOS、WPF 和 Android 中添加和应用自定义字体。

【讨论】:

我还为此写了一篇博客,可能会对某人有所帮助(我也添加了您的链接)sturla.io/font-images-in-xamarin-forms【参考方案3】:

从 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 文件中的控件引用别名,如下所示 &lt;Label Text="Username" FontFamily="OpenSans" /&gt;

【讨论】:

以上是关于Xamarin Forms 自定义字体 CrossPlatform的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin Forms:如何为自定义字体设置 FontAttributes Bold

Xamarin.Forms 中 Picker 的自定义渲染器

在 Xamarin Forms 自定义标签渲染器中,增加边界的大小

菜鸟的Xamarin.Forms前行之路——实现按钮的字体图标(可扩展)

如何在 Xamarin Forms iOS 中显示带有小型大写字体样式的标签?

Xamarin.Forms自定义GridView