At that time, the group temporarily received a request to change the font library. This request was relatively simple, because there were other things at hand, and I hadn’t changed the font library before, so I handed it over to my colleagues; now I have time to enrich myself (What I wrote may not be all right. If there are any deficiencies, you can directly raise them and discuss with each other)
在正式开始以前,你首先需要告知产品经理和设计师,因为引入新的字体库存在版权问题,需要对方授权方可使用,否则涉及侵权;如果产品确定一定要改的话,请产品和设计提供相关字体库
Before the beginning, I didn’t expect to write an article about the basic version of the font library. It took me two days to write more and more. I also referred to more than a dozen blogs, some new and some old. I hope this article will be helpful to you.
Look
: I don’t know if you have learned about font library related content when you read this article, let me first talk about the problems I encountered in seeking knowledge
What exactly is Android's default font? Why some say yes Source Han Sans(思源)
, some say yes Roboto
, some say yes DroidSans、DroidSansFallback
?
Regarding this question, I have looked through a bunch of articles, and the answers are all patchwork, similar, and there is no relatively complete explanation. Finally, I went outside to find a reasonable explanation. Let me integrate it (Hint: If you want To learn more, and have some personal interests, you can go to the basic cognition to continue to understand, welcome to discuss ~)
First of all Source Han Sans(思源)
, Roboto
, DroidSans、DroidSansFallback
fonts, and font libraries all exist, and they all exist in the Android system!
Among them, Source Han Sans(思源)
it is suitable for the Chinese environment & China, Japan and South Korea, Roboto
suitable for English & numbers, DroidSans、DroidSansFallback
suitable for countries other than China, Japan and South Korea or as a backup (default) font; ( 故知道国内用的是思源字体库+Roboto字体库即可
)
Business Requirements & Implementation
It is very simple to introduce and use a new font library. If it is only for business needs, just read this paragraph; if you are interested and have enough time, you can go through it~
Business needs
Because it is UI的设计需求
, we mainly look at the relevant data information of the design drawing
UI renderings
font-family (font library): Roboto-Medium;
Hint:根据设计图可以看出使用到的主要是 Roboto字体中的 中等加粗字体
business realization
Regarding the implementation of the font library business, I took a look at the implementation, mainly including 静态实现(xml)和动态实现(代码设置)
, specifically使用哪种方式取决于自己和业务场景的使用
Because the two methods are different for the storage location of the font library, there are 简单说明res、assets
similarities and differences in setting up small classrooms for seeking knowledge.
The same point: the files in the two directories are in打包后会原封不动的保存在apk包中,不会被编译成二进制
difference:
- The way to reference resources is different:
res/raw
the files in will be mapped to the R.java file, and the resource ID, namely R.id.filename, will be used directly when accessing;assets
the files under the folder will not be mapped to R.java, and the accessed WhenAssetManager
classes are needed. - Handled differently
- The subdirectories are different:
res/raw
there can be no directory structure, butassets
there can be a directory structure, that is, folders can be created under the assets directory
According to the font library provided, AndroidStudio
you can directly see the preview effect after decompression
Comprehensive realization effect
The effects of the two implementation methods are unified, but the static implementation supports preview, so the renderings are unified;
The view effects correspond to the following three categories (I can’t actually see much difference, maybe only the design is easier to distinguish)
默认字体
Roboto 普通字体
Roboto 加粗字体
static implementation
The advantage of static implementation is that it is easy to use, you can directly set attributes, and at the same time support direct observation of the setting effect; the disadvantage is that the product requires certain business scenarios, and you need to dynamically switch the font effect of the control (thousands of people and thousands of faces)
- used
res - 创建 font 文件夹
to store font libraries
- The commands about the font library need to comply
命名规范
(the naming is different compared to the dynamic implementation)
misnamed
use correctly
xml
Reference font library in
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="0.00" />
<TextView
android:id="@+id/tv_text1"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:fontFamily="@font/roboto_regular"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="0.08" />
<TextView
android:id="@+id/tv_text2"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:fontFamily="@font/roboto_medium"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="66.66" />
</LinearLayout>
preview effect
Dynamic implementation
The way of dynamic implementation is slightly different from that of static implementation. The first is the place where the resources are stored, and the second is the way to set the font library
- Create
assets
a folder
AndroidStudio
will automatically prompt
- Create a folder under the folder, which is mainly used to store the font
assets
libraryfonts
- The font library is generally
ttf
a file, we can place the fonts here, as follows
calling method
general settings
package com.example.kotlindemo
import android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.want_text_display)
var t1 = findViewById<TextView>(R.id.tv_text1)
val regular = Typeface.createFromAsset(assets,"fonts/Roboto-Regular.ttf")
t1.typeface = regular;
}
}
A single control generally uses the same font library style, here is the setting method of the two controls (the setting method is the same), I only wrote one more copy because I quoted the styles of the two font libraries,一个为roboto普通字体,一个为roboto加粗字体
package com.example.kotlindemo
import android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.want_text_display)
var t1 = findViewById<TextView>(R.id.tv_text1)
var t2 = findViewById<TextView>(R.id.tv_text2)
val regular = Typeface.createFromAsset(assets,"fonts/Roboto-Regular.ttf")
val medium = Typeface.createFromAsset(assets,"fonts/Roboto-Medium.ttf")
t1.typeface = regular;
t2.typeface = medium;
}
}
want_text_display
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="0.00" />
<TextView
android:id="@+id/tv_text1"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="0.08" />
<TextView
android:id="@+id/tv_text2"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="66.66" />
</LinearLayout>
Keep it as a memo
I read a blog before and saw that the ElegantTextHeight property should be set, otherwise the height will change, but I have not encountered the relevant scene, so I will keep it as a memo again
// 应用字体
var typeFace = Typeface.createFromAsset(mContext.getAssets(),"fonts/sourcehanserifcn_regular.otf")
//这个不可缺少,不加tvtext高度变大很多 很不美观
tvtext.setElegantTextHeight(true)
tvtext.setTypeface(typeFace)
Basic cognition
Android has its own 默认字体库
, but because of 国内厂商较多,大多都会定制化字体
, the display effects are different, and most of the time the fonts are not completely unified
针对于我们常见的中文、英文、数字使用的字体库也有所不同
Android default font
- Chinese font:
Source Han Sans / Noto
( Siyuan bold )
Wikipedia: Source Han Sans (English: Source Han Sans, the word "Siyuan" comes from the idiom "Drinking Water and Thinking of the Source") is an open source font family developed by Adobe and Google. Versions 1.001 and earlier are licensed under the Apache 2.0 license, while 1.002 and newer versions use the SIL open source font license, which belongs to sans-serif boldface. Siyuan HeiTi was first released on July 16, 2014. It supports Traditional Chinese, Simplified Chinese, Japanese and Korean, and each has 7 font weights. At the time of publication, it was the font with the largest number of characters at that time, with 44,666 characters belonging to 65,535 glyphs, which is the limit of OpenType font technology.
- Numbers & English fonts:
Roboto
small classroom
DroidSansFallback
and 思源黑体
are two different fonts, they have different functions and application scenarios in the Android system.
DroidSansFallback : DroidSansFallback
is a font library in the Android system for 支持多语言和字符集的显示
. It includes a wide Unicode
range of character coverage, including glyphs for some uncommon characters and languages. When the system cannot find an appropriate font to display a particular character, it uses DroidSansFallback
as a fallback font. This enables Android to display multiple languages and symbols, even if the default font library (such as Roboto) does not contain corresponding characters.
The following are the default fonts for the Android Android system:
Clockopia.ttf
System default standby clock font;DroidSansFallback.ttf
System default Chinese font;DroidSans.ttf
System default English font;DroidSans-Bold.ttf
The system default English bold font;
Siyuan Heiti : Siyuan Heiti is an open source font jointly developed by Adobe
and to support the display of Chinese, Japanese and Korean (CJK) languages. Google
It includes Chinese characters, Japanese kana and Korean characters, with a wide range of coverage. Siyuan blackface is designed to maintain the clarity and readability of fonts, while adapting to different screen sizes and resolutions. In some Chinese, Japanese and Korean language environments, the Android system will use Siyuan HeiTi as the default font to display the corresponding text content.
No matter which font library we use, the general font library will provide a variety of styles of fonts, such as regular, bold, etc., for exampleRegular、Italic、Bold、Bold-italic、Light、Light-italic、Thin、Thin-italic、Condensed regular、Condensed italic、Condensed bold、Condensed bold-italic
As a teammate, it is necessary to understandIOS 默认字体
- Medium font:
PingFang SC
- Numbers & English fonts:
.SF UI Text、.SF UI Display
Comparing with Chinese fonts, it can be seen 平方对比思源黑体,笔画更细、字怀更大、字体使用弧度更少,偏旁所占字面更小
(to be honest, I have to look at the design, I basically can't see much difference...).
Some supplementary introductions about the Roboto font
这部分内容是看百度发的一篇blog借鉴于此的(偏官方简介),仅做了解即可,无需细读,以下介绍均针对于Android客户端
font characteristics
清晰的字形
: Roboto font has very clear glyphs, which makes it very comfortable to read and write.可读性强
: The Roboto font has great readability, which means it will work well in most applications.平衡的间距
: Roboto also has a good balance of spacing between lines. This means that the layout of the text on the screen is very even, and it looks very neat.广泛的可用性
: Roboto font is an open source font, so it is widely used in the Android open source project. This makes it work well on a wide variety of devices and screen resolutions.
font advantages
看起来专业
: Use the Roboto font to give your application a more professional look. Its crisp glyphs and balanced spacing make text look sharper on screen.提高可读性
: Thanks to the excellent readability of the Roboto font, it is very comfortable to read and write, which also means that the usability of the application is improved.减少屏幕分辨率变化
: Since the Roboto font works well on various devices and screen resolutions, the application will not have a large impact on adapting to different screen sizes.延长设备电池寿命
: Some studies have shown that using the Roboto font can improve device battery life. This is because darker fonts reduce the need for screen brightness, which reduces battery drain.
Not enough fonts
应用程序的可读性降低
: If the text in the application uses a different font, it may cause the application to be less readable.应用程序的可用性降低
: If the Roboto font is used for the text in the application, and the device screen resolution is low, it may reduce the usability of the application.设备电池消耗增加
: There are some studies showing that using the Roboto font may lead to increased device battery consumption. This is because darker fonts may lead to increased demands on screen brightness, which increases battery consumption.
Manufacturer font
Android itself is highly customizable. Root was basically required when changing fonts in the early days. Nowadays, mobile phones come with this function, and each manufacturer has sufficient permissions. Own fonts; Most domestic manufacturers have their own fonts, for example,
Misans
,OPPO SANS
,HarmonyOS Sans
and other default fonts of some mobile phone manufacturers. These fonts not only support Chinese display, but also Western languages (such as English) can be perfectly displayed.
In an article, I saw the introduction of the default fonts of major mobile phone manufacturers . Here is just a summary of some key information.
This friend said that if the font is good, you need to pay attention to these three aspects: the number of characters should be large (to take care of some rare characters), the font weight should be complete (uniform thickness), and OpenType support (characters will be automatically adjusted according to the situation to make it look more beautiful. ).
Let's take a look at which of the three mainstream fonts looks better! Let me explain here again that these three fonts are customized by Hanyi, so not all fonts are customized by mobile phone manufacturers.
Misans
For the MIUI13
brand-new system fonts promoted inside MiSans
, the Chinese, English and digital designs are fully optimized, with simple fonts, clear vision, and comfortable reading.
Actually this MiSans
is 黑体的变种
. Although it is also in black, but in some details, it can be seen that it has really worked hard
- The pen is straight and strong
- Simpler design
- Reduce visual burden
- It is more conducive to the screen display
- Support OpenType function
MiSan
As soon as it comes out, especially in some scenes with long texts and punctuation marks, it is obvious that the so-called high-level sense is stronger, and Hongmeng fonts seem a little ordinary compared with it.
Huawei (HarmonyOS Sans)
- Support more languages;
- There are special enhanced fonts for italics and traditional Chinese;
- Mixed Chinese and English, text and punctuation marks are also very good, and there will be no blunt wrong lines, but the weight of the words is less than that of Xiaomi MiSans, only 6 kinds of weights.
OPPO(OPPO SANS)
- Brand new skeleton
- Natural comfort in the palace
- stable structure
- font stretch
- Enhanced screen display legibility and aesthetics
principle interest
How Android fonts work
android fonts android 2D图形引擎skia
are implemented by , and Zygote
in Preloading classes
the system fonts load
.
The relevant files are: skTypeface.cpp
and skFontHost_android.cpp
, where the latter is skia针对android平台字体实现的port
. The main variables are:
struct FontInitRec {
const char*
fFileName;const char* const* fNames;
// null-terminated list};struct FamilyRec {FamilyRec* fNext;SkTypeface* fFaces[5];};
//uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];load_system_fonts()@skFontHost_android.cpp
Load all the fonts in the system and assign a unique ID to each font, and divide the fonts into two types: FamilyFonts
and FallbackFonts
, and finally realize the display of characters through the ID corresponding to skPaint
the font ( ) set by the application .Typeface
Replace Android's default Chinese font
In android
the system, DroidSans
it is the default font, which only contains Western characters. The application will call it by default, but it DroidSansFallback
contains East Asian characters. When the characters to be displayed DroidSans
do not exist in the font (such as: Chinese characters), there is no corresponding encoding character, the system will DroidSansFallback
search for the character of the corresponding code, if found, it will use DroidSansFallback
the font to display it, if the character corresponding to the code is still not found, the character cannot be displayed on the screen.
Add a default font for the android system, similar to " sans”,“serif”,“monospace
"
In the android system, there is only one default Chinese font: DroidSansFallback.ttf
, if you want to set the desired Chinese font in the android application, in addition to importing the font file through the assets directory in the application, you can also add the android default font way to achieve. The steps to add are roughly as follows:
frameworks/base/data/fonts
Add font files under the directory, for exampleDriod-kaishu.ttf
;- Add the font of regular script in
skia
, the files that need to be modified mainly includeskFontHost.cpp、skTypeface.cpp、Typeface.java
; - Add regular script font-related APIs at
java
the layer, and the files that need to be modified mainly includetypeface.java和textview.java
; - Compile the SDK
- Import the newly generated sdk into the project, and you can set the font you added by yourself
setTypeface(Typeface.KAISHU)
and in two ways.android:typeface=(“kaishu”)