其时组内暂时接到一个换字体库的需求,这个需求相对简略,由于手头有其他作业,一起之前也没换过字体库,就交给了同事去做了;现在有时刻就好好充分下自己 ( 我写的也未必全对,如有缺乏可直接提出,相互讨论)

在正式开端以前,你首要需求告知产品司理和规划师,由于引进新的字体库存在版权问题,需求对方授权方可运用,不然触及侵权;假如产品确认一定要改的话,请产品和规划供给相关字体库

开篇前没想到写一篇根底版的字体库相关内容,用了小俩天时刻,越写越多,也参考了十几篇blog,有新有旧,希望该篇对你有所帮助

Look:不知道你在看此篇时,是否有了解过字体库相关内容,我先行说一下,我在求知中遇到的问题

Android的默许字体究竟是什么?为什么有的说是 Source Han Sans(思源),有的说是 Roboto,有的说是 DroidSans、DroidSansFallback

关于这个问题,我翻了一堆文章,答案都东拼西凑、大同小异,并没有一个比较完善的解说,终究还是去外面找到一个合理的解说,我来一致整合一下吧(Hint:假如你想了解更多,也有一些个人爱好,可前往根底认知中持续了解下,欢迎讨论~)

首要 Source Han Sans(思源)RobotoDroidSans、DroidSansFallback 字体、字体库都是存在的,且都是存在于Android体系中的!

其间 Source Han Sans(思源) 适用于中文环境 & 中日韩三国,Roboto适用于英文&数字, DroidSans、DroidSansFallback适用于中日韩以外的国家 或 作为备用(默许)字体;(故知道国内用的是思源字体库+Roboto字体库即可

事务需求&完成

引进、以及运用新的字体库,都很简略,假如只是为了完成事务需求的话,只看该段即可;假如有爱好,且时刻满足的话能够大致过一下~

事务需求

由于是UI的规划需求,咱们主要看规划图相关数据信息即可

UI作用图

Android进阶之路 - 深入浅出字体、字体库

font-family(字体库): Roboto-Medium;

Android进阶之路 - 深入浅出字体、字体库

Hint:依据规划图能够看出运用到的主要是 Roboto字体中的 中等加粗字体

事务完成

关于字体库事务的完成方法,我看了一下完成方法,主要有静态完成(xml)和动态完成(代码设置),具体运用哪种方法取决于自己和事务场景的运用

由于俩种先方法针对于字体库的存储方位有所不同,故开设求知小讲堂简略说明res、assets同异

相同点:两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制

不同点:

  • 引证资源的方法不同:res/raw中的文件会被映射到R.java文件中,拜访的时分直接运用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,拜访的时分需求AssetManager类。
  • 处理方法不同
  • 子目录不同:res/raw不能够有目录结构,而assets则能够有目录结构,也便是assets目录下能够再树立文件夹

依据触及供给的字体库,解压后放在AndroidStudio内能够直接看预览作用

Android进阶之路 - 深入浅出字体、字体库

归纳完成作用

俩种完成方法的作用是一致的,只是静态完成支撑预览,故一致作用图;

视图作用分别对应以下三类(我其实看不出太大差异,或许只要规划比较简单区分)

  • 默许字体
  • Roboto 普通字体
  • Roboto 加粗字体
    Android进阶之路 - 深入浅出字体、字体库

静态完成

静态完成的优势在于运用方便,能够直接设置特点,一起支撑直接调查设置作用;缺乏之处在于产品要求某些事务场景,需求动态切换控件的字体作用(千人千面)

  1. res - 创立 font 文件夹用于寄存字体库
    Android进阶之路 - 深入浅出字体、字体库
  2. 关于字体库的指令需求契合命名标准(比照动态完成命名有所不同)

错误命名

Android进阶之路 - 深入浅出字体、字体库

正确运用

Android进阶之路 - 深入浅出字体、字体库

xml 中引证字体库

<?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>

预览作用

Android进阶之路 - 深入浅出字体、字体库

动态完成

动态完成的方法同静态完成稍有不同,首要是资源存储的地方,其次是设置字体库的方法

  1. 创立assets文件夹
    Android进阶之路 - 深入浅出字体、字体库
    AndroidStudio 会主动提示
    Android进阶之路 - 深入浅出字体、字体库
  2. assets 文件夹下创立 fonts 文件夹,主要用于存储字体库
    Android进阶之路 - 深入浅出字体、字体库
  3. 字体库一般为 ttf 文件,咱们将字体与放置于此即可,总体如下
    Android进阶之路 - 深入浅出字体、字体库

调用方法

惯例设置

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;
    }
}

单控件一般选用同一个字体库款式,这儿是俩个控件的设置方法(设置方法相同),只所以多写一份是由于我引证了俩个字体库的款式,一个为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>

留作备忘

我之前翻了一篇blog,看到说要设置ElegantTextHeight特点,不然高度会发生改变,可是我并未遇到相关场景,故再次留作备忘

// 运用字体
var typeFace = Typeface.createFromAsset(mContext.getAssets(),"fonts/sourcehanserifcn_regular.otf")
//这个不可缺少,不加tvtext高度变大很多  很不漂亮
tvtext.setElegantTextHeight(true)
tvtext.setTypeface(typeFace)

根底认知

Android 拥有着属于自己的默许字体库,不过由于国内厂商较多,大多都会定制化字体,所以显现作用各有不同,大多数时分字体并未彻底一致

针对于咱们常见的中文、英文、数字运用的字体库也有所不同

Android 默许字体

  • 中文字体:Source Han Sans / Noto(思源黑体)

维基百科:思源黑体(英语:Source Han Sans,“思源”一词来自于成语“饮水思源”)是Adobe与Google所领导开发的开源字体宗族,1.001及更早版别以Apache 2.0许可证许可,而1.002及更新版别则运用SIL开源字体授权,属于无衬线黑体。思源黑体于2014年7月16日首次发布,支撑繁体中文、简体中文、日文及韩文,而且各有7种字体粗细。公开之时为其时包括字符数量最多的字体,44,666 个字符分属于 65,535 个字形中,此为OpenType字体技术的极限。

  • 数字&英文字体:Roboto

小讲堂

DroidSansFallback思源黑体是两种不同的字体,它们在 Android 体系中具有不同的作用和运用场景。

DroidSansFallbackDroidSansFallback 是 Android 体系中的一个字体库,用于支撑多语言和字符集的显现。它包含了广泛的 Unicode 字符掩盖规模,包括了一些不常见的字符和语言的字形。当体系无法找到适当的字体来显现特定字符时,它会运用 DroidSansFallback 来作为回退字体。这使得 Android 能够显现多种语言和符号,即便默许字体库(如 Roboto)没有包含对应的字符。

以下是Android安卓体系默许的几种字体:

  • Clockopia.ttf 体系默许待机时钟字体;
  • DroidSansFallback.ttf 体系默许中文字体;
  • DroidSans.ttf 体系默许英文字体;
  • DroidSans-Bold.ttf 体系默许英文粗字体;

思源黑体:思源黑体是一种由 AdobeGoogle 共同开发的开源字体,用于支撑中日韩(CJK)语言的显现。它包含了汉字、日文假名和韩文字符,具有广泛的掩盖规模。思源黑体在规划上重视坚持字形的明晰度和可读性,一起习惯不同的屏幕尺寸和分辨率。在一些中日韩语言环境下,Android 体系会运用思源黑体作为默许的字体来显现相应的文字内容。

不论咱们运用哪种字体库,一般字体库都会供给字体的多种款式,例如惯例、加粗等,例如 Regular、Italic、Bold、Bold-italic、Light、Light-italic、Thin、Thin-italic、Condensed regular、Condensed italic、Condensed bold、Condensed bold-italic

作为队友,有必要了解下 IOS 默许字体

  • 中文字体:PingFang SC
  • 数字&英文字体:.SF UI Text、.SF UI Display

默默 copy 俩张图

Android进阶之路 - 深入浅出字体、字体库

以中文字体来做比照,能够看出平方比照思源黑体,笔画更细、字怀更大、字体运用弧度更少,偏旁所占字面更小(说实话,还得规划来看,我根本看不出什么太大差异…)。

Android进阶之路 - 深入浅出字体、字体库

关于Roboto字体的一些补充介绍

这部分内容是看百度发的一篇blog学习于此的(偏官方简介),仅做了解即可,无需细读,以下介绍均针对于Android客户端

字体特点

  • 明晰的字形:Roboto字体有着十分明晰的字形,这使得它在阅览和书写时十分舒适。
  • 可读性强:Roboto字体具有很好的可读性,这意味着在大多数运用程序中它都能很好地适用。
  • 平衡的间距:Roboto字体在行与行之间的间距上也有很好的平衡。这意味着文本在屏幕上的布局十分均匀,看起来十分整齐。
  • 广泛的可用性:Roboto字体是一种开源字体,因而它在Android开源项目中被广泛运用。这使得它在各种设备和屏幕分辨率上都能很好地适用。

字体优点

  • 看起来专业:运用Roboto字体能够使运用程序看起来愈加专业化。它的明晰字形和平衡的间距使得文本在屏幕上看起来愈加明晰。
  • 进步可读性:由于Roboto字体的可读性很好,因而在阅览和书写时十分舒适,这也意味着运用程序的可用性得到了进步。
  • 削减屏幕分辨率改变:由于Roboto字体在各种设备和屏幕分辨率上都能很好地适用,因而运用程序在习惯不同屏幕大小时不会产生过大的影响。
  • 延伸设备电池寿数:一些研讨标明,运用Roboto字体能够延伸设备电池寿数。这是由于较暗的字体能够削减屏幕亮度的需求,然后削减了电池的耗费。

字体缺乏

  • 运用程序的可读性降低:假如运用程序中的文本运用了不太相同的字体,那么或许会导致运用程序的可读性降低。
  • 运用程序的可用性降低:假如运用程序中的文本运用了Roboto字体,而设备屏幕分辨率较低,那么或许会导致运用程序的可用性降低。
  • 设备电池耗费增加:有一些研讨标明,运用Roboto字体或许会导致设备电池耗费增加。这是由于较暗的字体或许会导致屏幕亮度的需求增加,然后增加了电池的耗费。

厂商字体

Anddroid自身的定制性较强,早期换字体的时分根本上需求root,如今手机自带这个功用,各厂商也有了满足的权限,所以在看到我们对体系默许字体不是很喜欢时,就努力研制自家的字体;针对国内的厂商大多都有自定的字体,例如 MisansOPPO SANSHarmonyOS Sans 等一些手机厂商默许的字体。这些字体不仅支撑中文显现,连西文(如英文)都能完美显现。

在一篇文章内看到介绍了 各大手机厂商的默许字体,此处仅做一些要害信息摘要

这位朋友说字体好不好,还需注意这三个方面:字符数要多(照顾部分生僻字)、字重完全(粗细均匀)、OpenType支撑(字符依据情况主动调整,使其看起来愈加漂亮)。

咱们来看看干流的这三款字体哪个更好看吧!这儿再说明一下,这三款字体都是汉仪定制字体,因而字体不全是手机厂商定制。

小米(Misans)

针对于MIUI13里边宣扬的全新体系字体MiSans,全方位优化中英文及数字规划,字形精约,视觉明晰,阅览舒适。

其实这个MiSans算是黑体的变种。虽然也是黑体,可是在一些细节处能看出是真下了功夫

  • 笔型平直有力
  • 规划愈加精约
  • 削减视觉担负
  • 更有利于屏幕显现
  • 支撑OpenType功用

MiSan一出,尤其是在一些长文和标点符号比较多的场景下,显着所谓的高档感更强,而鸿蒙字体与其相比就显得普通了一些。

华为(HarmonyOS Sans)

  • 支撑更多的语言;
  • 对斜体和繁体中文有专门的加强字体;
  • 中英文混排、文字和标点符号混排感觉也是适当优秀,不会呈现很僵硬的错行,可是字重比小米MiSans要少,只要6种字重。

OPPO(OPPO SANS)

  • 全新骨架
  • 中宫天然舒适
  • 结构稳定
  • 字形舒展
  • 强化了屏幕显现的易读性和漂亮性

原理爱好

Android字体作业原理

android字体由android 2D图形引擎skia完成,并在ZygotePreloading classes中对体系字体进行load

相关文件有:skTypeface.cppskFontHost_android.cpp,其间后者是skia针对android渠道字体完成的port。主要的变量有:

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体系中所有的字体并给每种字体分配唯一的ID,并将字体分为两种:FamilyFontsFallbackFontsskPaint经过运用程序设置的字体(Typeface)所对应的ID终究完成字符的显现。

替换Android默许的汉字字体

android体系中,DroidSans是默许字体,只包含西方字符,运用程序默许情况下都会调用它,而DroidSansFallback包含了东亚字符,当需求显现的字符在DroidSans字体中不存在(如:汉字)时,即没有对应编码的字符时,体系会到DroidSansFallback中去找相应编码的字符,假如找到,则运用DroidSansFallback字体来显现它,假如仍找不到该编码对应的字符,则无法在屏幕上显现该字符。

为android体系增加一种默许字体,类似"sans","serif","monospace"

在android体系中,默许的中文字体只要一种:DroidSansFallback.ttf,假如想在android运用程序中随意设置想要的中文字体,除了在运用程序中经过assets目录引进字体文件外,还能够经过增加android默许字体的方法来完成。增加步骤大致如下:

  1. frameworks/base/data/fonts 目录下增加字体文件,例如 Driod-kaishu.ttf;
  2. skia中增加楷书这一字体,需求修正的文件主要有skFontHost.cpp、skTypeface.cpp、Typeface.java等;
  3. java层增加楷书字体相关API,需求修正的文件主要有typeface.java和textview.java;
  4. 编译SDK
  5. 将新生成的sdk导入项目,可经过setTypeface(Typeface.KAISHU)android:typeface=(“kaishu”)两种方法设置自己增加的字体。