是否可以为整个应用程序设置自定义字体?
我需要在整个应用程序中使用某种字体。我有相同的 .ttf 文件。 是否可以在应用程序启动时将其设置为默认字体,然后在应用程序的其他地方使用它?设置后,如何在布局 XML 中使用它?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我需要在整个应用程序中使用某种字体。我有相同的 .ttf 文件。 是否可以在应用程序启动时将其设置为默认字体,然后在应用程序的其他地方使用它?设置后,如何在布局 XML 中使用它?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(25)
是的,有反思。这是可行的(基于此答案):(
注意:这是一种解决方法,因为缺乏对自定义字体的支持,因此如果您想改变这种情况,请给 android 问题在这里)。 注意:不要在该问题上留下“我也是”评论,当您这样做时,每个关注该问题的人都会收到一封电子邮件。所以请给它“加注星标”。
然后,您需要重载一些默认字体,例如在 应用程序 中class:
或者当然,如果您使用相同的字体文件,您可以对此进行改进以仅加载一次。
然而,我倾向于只覆盖一个,比如“MONOSPACE”,然后设置一种样式来强制该字体应用程序广泛使用:
API 21 Android 5.0
我已经调查了评论中的报告,它没有不起作用,并且它似乎与主题
android:Theme.Material.Light
不兼容。如果该主题对您不重要,请使用较旧的主题,例如:
Yes with reflection. This works (based on this answer):
(Note: this is a workaround due to lack of support for custom fonts, so if you want to change this situation please do star to up-vote the android issue here). Note: Do not leave "me too" comments on that issue, everyone who has stared it gets an email when you do that. So just "star" it please.
You then need to overload the few default fonts, for example in an application class:
Or course if you are using the same font file, you can improve on this to load it just once.
However I tend to just override one, say
"MONOSPACE"
, then set up a style to force that font typeface application wide:API 21 Android 5.0
I've investigated the reports in the comments that it doesn't work and it appears to be incompatible with the theme
android:Theme.Material.Light
.If that theme is not important to you, use an older theme, e.g.:
android 中有一个很棒的自定义字体库:Calligraphy
这里是如何使用它的示例。
在 Gradle 中,您需要将此行放入应用程序的 build.gradle 文件中:
然后创建一个扩展
Application
的类并编写此代码:并在 Activity 类中将此方法放在 onCreate:
和最后一个之前你的清单文件应该看起来像这样:
它会将整个活动更改为你的字体!简单又干净!
There is a great library for custom fonts in android:Calligraphy
here is a sample how to use it.
in Gradle you need to put this line into your app's build.gradle file:
and then make a class that extends
Application
and write this code:and in the activity class put this method before onCreate:
and the last thing your manifest file should look like this:
and it will change the whole activity to your font! it's simple and clean!
虽然这不适用于整个应用程序,但它适用于活动,并且可以重新用于任何其他活动。感谢@FR073N,我更新了我的代码以支持其他视图。我不确定
Buttons
、RadioGroups
等的问题,因为这些类都扩展了TextView
,所以它们应该可以正常工作。我添加了一个布尔条件来使用反射,因为它看起来非常hackish并且可能会显着影响性能。注意:正如所指出的,这不适用于动态内容!为此,可以使用
onCreateView
或getView
方法调用此方法,但需要额外的工作。然后要使用它,你会做这样的事情:
希望有帮助。
While this would not work for an entire application, it would work for an Activity and could be re-used for any other Activity. I've updated my code thanks to @FR073N to support other Views. I'm not sure about issues with
Buttons
,RadioGroups
, etc. because those classes all extendTextView
so they should work just fine. I added a boolean conditional for using reflection because it seems very hackish and might notably compromise performance.Note: as pointed out, this will not work for dynamic content! For that, it's possible to call this method with say an
onCreateView
orgetView
method, but requires additional effort.Then to use it you would do something like this:
Hope that helps.
总之:
选项#1:使用反射来应用字体(结合 weston 和 Roger Huang 的答案):
Application 类中的用法:
设置一种样式以强制该字体应用于整个应用程序(基于 lovefish):
Pre-Lollipop:
Lollipop (API 21):
Option2: 子类化每个视图,其中您需要自定义字体,即。 ListView、EditTextView、Button 等(Palani 的回答):
选项 3: 实施遍历当前屏幕的视图层次结构的视图爬行程序:
Variation#1(Tom 的回答):
用法:
变体#2: https://coderwall.com/p/qxxmaa /android-use-a-custom-font-everywhere。
选项 #4: 使用名为 Calligraphy 的 3rd 方库。
就我个人而言,我会推荐选项#4,因为它可以省去很多麻烦。
In summary:
Option#1: Use reflection to apply font (combining weston & Roger Huang's answer):
Usage in Application class:
set up a style to force that font typeface application wide (based on lovefish):
Pre-Lollipop:
Lollipop (API 21):
Option2: Subclass each and every View where you need to customize font, ie. ListView, EditTextView, Button, etc. (Palani's answer):
Option 3: Implement a View Crawler that traverses through the view hierarchy of your current screen:
Variation#1 (Tom's answer):
Usage :
Variation#2: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere.
Option #4: Use 3rd Party Lib called Calligraphy.
Personally, I would recommend Option#4, as it saves a lot of headaches.
我想改进 weston 对 API 21 Android 5.0 的回答。
原因
在 API 21 下,大多数文本样式都包含 fontFamily 设置,例如:
应用默认的 Roboto Regular 字体:
原始答案无法应用等宽字体,因为 android:fontFamily 比 android:typeface 属性具有更高的优先级(参考)。
使用 Theme.Holo.* 是一个有效的解决方法,因为里面没有 android:fontFamily 设置。
解决方案
自 Android 5.0 将系统字体放入静态变量 Typeface.sSystemFontMap (参考),我们可以使用使用相同的反射技术来替换它:
I would like to improve weston's answer for API 21 Android 5.0.
Cause
Under API 21, most of the text styles include fontFamily setting, like:
Which applys the default Roboto Regular font:
The original answer fails to apply monospace font, because android:fontFamily has greater priority to android:typeface attribute (reference).
Using Theme.Holo.* is a valid workaround, because there is no android:fontFamily settings inside.
Solution
Since Android 5.0 put system typeface in static variable Typeface.sSystemFontMap (reference), we can use the same reflection technique to replace it:
它非常简单...
1.下载自定义字体并将其放入资产中。然后为文本视图编写一个单独的类,如下所示:这里我使用了futura字体
}
并在xml中执行以下操作:
its very simple...
1.Download and put ur custom font in assets..then write one separate class for text view as follows: here i used futura font
}
and do the following in xml :
我还建议扩展 TextView 和其他控件,但我最好考虑在构造中设置字体。
I would also suggest extending TextView and other controls, but it would be better I consider to set up font in constructs.
可以在这里找到一个出色的解决方案:https://coderwall。 com/p/qxxmaa/android-use-a-custom-font-everywhere。
只需从 BaseActivity 扩展活动并编写这些方法即可。此外,您应该更好地缓存字体,如下所述:https://stackoverflow.com/a/16902532/2914140。
经过一番研究,我编写了适用于 Samsung Galaxy Tab A (Android 5.0) 的代码。使用了 weston 和 Roger Huang 的代码以及 https://stackoverflow.com/a/33236102/2914140。还在 Lenovo TAB 2 A10-70L 上进行了测试,但无法正常工作。
我在这里插入了“Comic Sans”字体以查看差异。
要在整个应用程序中运行代码,您应该在诸如应用程序之类的类中编写以下内容:
在“资产”内创建一个文件夹“字体”,并将所需的字体放在那里。可以在这里找到简单的说明:https://stackoverflow.com/a/31697103/2914140。
Lenovo 设备还会错误地获取字体值。大多数时候它返回 Typeface.NORMAL,有时返回 null。即使 TextView 是粗体的(在 xml 文件布局中)。请参阅此处:TextView isBold 始终返回 NORMAL。这样,屏幕上的文本始终采用常规字体,而不是粗体或斜体。所以我认为这是制作人的错误。
A brilliant solution can be found here: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere.
Simply extend activities from BaseActivity and write those methods. Also you should better cache fonts as described here: https://stackoverflow.com/a/16902532/2914140.
After some research I wrote code that works at Samsung Galaxy Tab A (Android 5.0). Used code of weston and Roger Huang as well as https://stackoverflow.com/a/33236102/2914140. Also tested on Lenovo TAB 2 A10-70L, where it doesn't work.
I inserted a font 'Comic Sans' here in order to see a difference.
To run the code in entire application you should write in some class like Application the following:
Create a folder 'fonts' inside 'assets' and put needed fonts there. A simple instruction may be found here: https://stackoverflow.com/a/31697103/2914140.
The Lenovo device also incorrectly gets a value of a typeface. In most times it returns Typeface.NORMAL, sometimes null. Even if a TextView is bold (in xml-file layout). See here: TextView isBold always returns NORMAL. This way a text on a screen is always in a regural font, not bold or italic. So I think it's a bug of a producer.
我想改进 weston 和 Roger Huang 针对主题为“Theme.AppCompat”的 API 21 Android 棒棒糖的回答。
Android 4.4
以上(等于)API 5.0
以下,FontsOverride util文件与weston 的回答。
我在这些手机中进行了测试:
Nexus 5(android 5.1 Primary Android System)
ZTE V5(android 5.1 CM12.1)
XIAOMI note(android 4.4 MIUI6)
HUAWEI C8850(android 2.3.5 UNKNOWN)
I would like to improve weston's and Roger Huang's answers for over API 21 Android lollipop with theme "Theme.AppCompat".
Below Android 4.4
Over(equal) API 5.0
And the FontsOverride util file is same as what in weston's answer.
I have tested in these phones:
Nexus 5(android 5.1 Primary Android System)
ZTE V5(android 5.1 CM12.1)
XIAOMI note(android 4.4 MIUI6)
HUAWEI C8850(android 2.3.5 UNKNOWN)
适用于 Xamarin.Android:
类:
应用程序实现:
样式:
Working for Xamarin.Android:
Class:
Application Implementation:
Style:
从 Android O 开始,现在可以直接从 XML 定义,我的错误现已关闭!
请参阅此处了解详细信息
TL ;DR:
首先,您必须将字体添加到项目中
,然后添加字体系列,如下所示:
最后,您可以在布局或样式中使用该字体:
享受吧!
As of Android O this is now possible to define directly from the XML and my bug is now closed!
See here for details
TL;DR:
First you must add your fonts to the project
Second you add a font family, like so:
Finally, you can use the font in a layout or style:
Enjoy!
您可以为每个布局一一设置自定义字体,只需通过传递其根视图从每个布局调用一个函数。首先,创建一个单独的方法来访问像这样的字体对象
您可以在上面的类中定义不同的字体,现在定义一个将应用字体的 font Helper 类:
在上面的代码中,我仅在 textView 和 EditText 上应用字体,您也可以类似地在其他视图元素上应用字体。您只需将根视图组的 id 传递给上面的应用字体方法。例如,您的布局是:
在上面的布局中,根父 ID 是“Main Parent”,现在让我们应用字体
Cheers :)
You can set custom fonts for every layout one by one ,with just one function call from every layout by passing its root View.First ,create a singelton approach for accessing font object like this
You can define different fonts in above class, Now Define a font Helper class that will apply fonts :
In the above code, I am applying fonts on textView and EditText only , you can apply fonts on other view elements as well similarly.You just need to pass the id of your root View group to the above apply font method. for example your layout is :
In the Above Layout the root parent id is "Main Parent " now lets apply font
Cheers :)
我建议扩展 TextView,并始终在 XML 布局中或任何需要 TextView 的地方使用自定义 TextView。在您的自定义 TextView 中,覆盖
setTypeface
I would suggest extending TextView, and always using your custom TextView within your XML layouts or wherever you need a TextView. In your custom TextView, override
setTypeface
Tom 的解决方案效果很好,但仅适用于 TextView 和 EditText。
如果您想覆盖大多数视图(RadioGroup、TextView、Checkbox...),我创建了一个方法来执行此操作:
此方法将返回 XML 中设置的视图样式(粗体、斜体...)并应用如果它们存在的话。
对于 ListView,我总是创建一个适配器,并在 getView 中设置字体。
Tom's solution works great, but only works with TextView and EditText.
If you want to cover most of the views (RadioGroup, TextView, Checkbox...), I created a method doing that :
This method will get back the style of the view set in XML (bold, italic...) and apply them if they exists.
For the ListView, I always create an adapter, and I set the font inside getView.
我编写了一个类,将字体分配给当前视图层次结构中的视图,并基于操作系统当前的字体属性(粗体、正常,如果需要,您可以添加其他样式):
现在在 onViewCreated 或 onCreateView 中的所有片段中,在 onCreate 中的所有活动中并且在 getView 或 newView 中的所有视图适配器中只需调用:
I wrote a class assigning typeface to the views in the current view hierarchy and based os the current typeface properties (bold, normal, you can add other styles if you want):
Now in all fragments in onViewCreated or onCreateView, in all activities in onCreate and in all view adapters in getView or newView just invoke:
在 api 26 中,使用 build.gradle 3.0.0 及更高版本,您可以在 res 中创建一个字体目录
并在您的样式中使用此行
进行更改 build.gradle 在您的 build.gradle 依赖项中使用此行
in api 26 with build.gradle 3.0.0 and higher you can create a font directory in res
and use this line in your style
for change build.gradle use this in your build.gradle dependecies
最后,Google 意识到这个问题的严重性(将自定义字体应用于 UI 组件),并为此设计了一个干净的解决方案。
首先,你需要更新支持库26+(你可能还需要更新你的gradle{4.0+}、android studio),然后你可以创建一个名为font的新资源文件夹。在此文件夹中,您可以放置字体资源(.tff,...)。
然后您需要覆盖默认应用程序并强制将您的自定义字体放入其中:)
注意:如果您想支持 API 版本低于 16 的设备,则必须使用应用程序命名空间而不是 android!
Finally, Google realized the severity of this problem (applying custom font to UI components) and they devised a clean solution for it.
First, you need to update to support library 26+ (you may also need to update your gradle{4.0+}, android studio), then you can create a new resource folder called font. In this folder, you can put your font resources (.tff,...).
Then you need to override the default app them and force your custom font into it :)
Note: if you want to support devices with older API than 16, you have to use app namespace instead of android!
我还想改进韦斯顿对 API 21 Android 5.0 的回答。
当我使用 DEFAULT 字体时,我在 Samsung s5 上也遇到了同样的问题。 (与其他字体一起工作正常)
我设法通过在 XML 文件中为每个 Textview 或 Button
以及 MyApplication 类设置字体(例如“sans”)来使其工作:
希望它有帮助。
I would also like to improve weston's answer for API 21 Android 5.0.
I had the same issue on my Samsung s5, when using DEFAULT font. (with the others fonts it's working fine)
I managed to make it working by setting the typeface ("sans" for example) in XML files, for each Textview or Button
and in MyApplication Class :
Hope it helps.
此解决方案在某些情况下无法正常工作。
所以我扩展了它:
FontsReplacer.java
https://gist.github.com/orwir/6df839e3527647adc2d56bfadfaad805
This solution does not work correctly in some situations.
So I extend it:
FontsReplacer.java
https://gist.github.com/orwir/6df839e3527647adc2d56bfadfaad805
Calligraphy 效果很好,但它不适合我,因为它不支持不同的粗细(粗体、斜体等)用于字体系列。
所以我尝试了 Fontain,它允许您定义自定义视图并应用它们自定义字体系列。
为了使用 Fontain,您应该将以下内容添加到您的应用程序模块 build.gradle:
然后,您应该使用 FontTextView,而不是使用常规 TextView,
其中包含大写和粗体内容的 FontTextView 示例:
Calligraphy works pretty well, but it is not suitable for me, since it does not support different weights (bold, italic, etc) for a font-family.
So I tried Fontain, which allows you to define custom Views and apply them custom font families.
in order to use Fontain, you should add the following to your app module build.gradle:
Then, instead of using regular TextView, you should use FontTextView
Example of FontTextView with uppercase and bold content:
要更改 TextView 的默认字体系列,请覆盖应用主题中的 textViewStyle。
要在 fontFamily 中使用自定义字体,请使用支持库中的字体资源。
该功能已在 Android 26 中添加,但通过 supportlib 向后移植到旧版本。
https://developer.android.com/guide/topics/resources/字体资源.html
https: //developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html#using-support-lib
For changing default font family of the TextViews, override textViewStyle in your app theme.
For using custom font in fontFamily, use font resources which is in support library.
The feature was added in Android 26 but backported to older versions via supportlib.
https://developer.android.com/guide/topics/resources/font-resource.html
https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html#using-support-lib
自从 Android Oreo 及其支持库 (26.0.0) 发布以来,您可以轻松地做到这一点。请参阅此答案在另一个问题中。
基本上你的最终风格将如下所示:
Since the release of Android Oreo and its support library (26.0.0) you can do this easily. Refer to this answer in another question.
Basically your final style will look like this:
我发现了 calligraphy 3 库 和 coderwall 的帖子 作为我的最终结果。
I found the mixture of calligraphy 3 library and coderwall's post as my ultimate result.
是的,可以为整个应用程序设置字体。
实现此目的的最简单方法是将所需的字体与您的应用程序打包在一起。
为此,只需在项目根目录中创建一个 assets/ 文件夹,然后将您的字体(在
资产中的 TrueType(或 TTF 形式)。
例如,您可以创建 assets/fonts/ 并将 TTF 文件放入其中。
Yes, its possible to set the font to the entire application.
The easiest way to accomplish this is to package the desired font(s) with your application.
To do this, simply create an assets/ folder in the project root, and put your fonts (in
TrueType, or TTF, form) in the assets.
You might, for example, create assets/fonts/ and put your TTF files in there.