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属性可以这样设置
<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 <Label Text="Hello World !" FontFamily="Binding FontFamily"/>
中定义的标签,但又一次,没有成功..
我完全被困住了...谁能帮助制作教程或解释我在教程后提到的每件事。感谢您的帮助!
【问题讨论】:
阅读该指南链接的博客条目,它对修改 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 文件中的控件引用别名,如下所示
<Label Text="Username" FontFamily="OpenSans" />
。
【讨论】:
以上是关于Xamarin Forms 自定义字体 CrossPlatform的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin Forms:如何为自定义字体设置 FontAttributes Bold
Xamarin.Forms 中 Picker 的自定义渲染器
在 Xamarin Forms 自定义标签渲染器中,增加边界的大小
菜鸟的Xamarin.Forms前行之路——实现按钮的字体图标(可扩展)