当时组内临时接到一个换字体库的需求,这个需求相对简单,因为手头有其他事情,同时之前也没换过字体库,就交给了同事去做了;现在有时间就好好充实下自己 ( 我写的也未必全对,如有不足可直接提出,相互探讨)

在正式开始以前,你首先需要告知产品经理和设计师,因为引入新的字体库存在版权问题,需要对方授权方可使用,否则涉及侵权;如果产品确定一定要改的话,请产品和设计提供相关字体库

  • 业务需求&实现
    • 业务需求
    • 业务实现
      • 静态实现
      • 动态实现
  • 基础认知
  • 厂商字体
    • 小米(Misans)
    • 华为(HarmonyOS Sans)
    • OPPO(OPPO SANS)
  • 原理兴趣

开篇前没想到写一篇基础版的字体库相关内容,用了小俩天时间,越写越多,也参考了十几篇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效果图

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

Hint:根据设计图可以看出使用到的主要是 Roboto字体中的 中等加粗字体

业务实现

关于字体库业务的实现方式,我看了一下实现方式,主要有静态实现(xml)和动态实现(代码设置),具体使用哪种方式取决于自己和业务场景的使用

因为俩种先方式针对于字体库的存储位置有所不同,故开设求知小课堂简单说明res、assets同异

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

不同点:

  • 引用资源的方式不同:res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
  • 处理方式不同
  • 子目录不同:res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹

根据涉及提供的字体库,解压后放在AndroidStudio内可以直接看预览效果

综合实现效果

俩种实现方式的效果是统一的,只是静态实现支持预览,故统一效果图;

视图效果分别对应以下三类(我其实看不出太大区别,可能只有设计比较容易辨别)

  • 默认字体
  • Roboto 普通字体
  • Roboto 加粗字体

静态实现

静态实现的优势在于使用方便,可以直接设置属性,同时支持直接观察设置效果;不足之处在于产品要求某些业务场景,需要动态切换控件的字体效果(千人千面)

  1. res - 创建 font 文件夹用于存放字体库
  2. 关于字体库的命令需要符合命名规范(对比动态实现命名有所不同)

错误命名

正确使用

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"><TextViewandroid:layout_width="wrap_content"android:layout_height="40dp"android:layout_marginTop="20dp"android:gravity="center"android:text="0.00" /><TextViewandroid: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" /><TextViewandroid: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>

预览效果

动态实现

动态实现的方式同静态实现稍有不同,首先是资源存储的地方,其次是设置字体库的方式

  1. 创建assets文件夹

    AndroidStudio 会自动提示
  2. assets 文件夹下创建 fonts 文件夹,主要用于存储字体库
  3. 字体库一般为 ttf 文件,我们将字体与放置于此即可,总体如下

调用方式

常规设置

package com.example.kotlindemoimport android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivityclass 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.kotlindemoimport android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivityclass 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"><TextViewandroid:layout_width="wrap_content"android:layout_height="40dp"android:layout_marginTop="20dp"android:gravity="center"android:text="0.00" /><TextViewandroid:id="@+id/tv_text1"android:layout_width="wrap_content"android:layout_height="40dp"android:layout_marginTop="10dp"android:gravity="center"android:text="0.08" /><TextViewandroid: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 俩张图

以中文字体来做对比,可以看出平方对比思源黑体,笔画更细、字怀更大、字体使用弧度更少,偏旁所占字面更小(说实话,还得设计来看,我基本看不出什么太大区别…)。

关于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”)两种方式设置自己添加的字体。

Android进阶之路 - 深入浅出字体、字体库相关推荐

  1. Android进阶之路 - 解决部分手机拍照之后图片被旋转的问题

    这几天犯了一个错误,初期想着甩锅给后台的- 但还好及时发现了是自身的问题~ 关联文章 Android基础进阶 - 调用拍照.获取图片(基础) Android基础进阶 - 获取.调用相册内图片(基础) ...

  2. Android进阶之路 - 批量下载、缓存图片、视频

    之前已经记录过,批量下载图片和缓存本地的方式,此篇主要记录批量下载图片.视频,同时缓存在本地的功能实现 关联篇 Android进阶之路 - 批量下载.缓存图片 Android进阶之路 - 批量下载.缓 ...

  3. Android进阶之路 - 软键盘中右下角的设置与监听

    在项目中,多多少少会遇到修改软键盘右下角按钮的需求,虽然已经写过几次,但是还是觉得在这里专心做个笔记比较放心 ~ 我的那些软键盘Blog ~ Android进阶之路 - 常见软键盘操作行为 Andro ...

  4. Android进阶之路 - 批量下载、缓存图片

    在日常项目开发中,关于图片批量下载,数据缓存的相关功能比比皆是,这次也是去年在项目中需要在本地缓存商品数据,所以用到了批量下载的功能,特此记录 ~ 关联篇 Android进阶之路 - 批量下载.缓存图 ...

  5. Android进阶之路 - 存、取、读 本地 Json 文件

    最近在开发中又开始加载一些本地的json数据源,回头看之前竟然没记录,赶紧记录一波 ~ 如何准备一个合格的json文件? AndoridStudio中如何存放json文件? 如何读取本地Json文件数 ...

  6. 浅谈Android进阶之路

    原址 过去十年是移动互联网蓬勃发展的黄金期,相信每个人也都享受到了移动互联网红利,在此期间,移动互联网经历了曙光期.成长期.成熟期.现在来说已经进入饱和期.依然记得在 2010-2013 年期间,从事 ...

  7. Android 进阶之路:ASM 修改字节码,这样学就对了!

    本文已授权个人公众号「鸿洋」原创发布. 恢复双休了,准备捡起来写博客这件事,会尝试写好每一篇博客,准备写一个「进阶之路」的系列,希望对你有用. 没错,看了很多 ASM 入门的文章,都感觉文章写的很轻松 ...

  8. Android 进阶之路(我的博客文章目录)

    原文地址:http://blog.csdn.net/u011240877 为了方便读者阅读以及自己回顾,总结写过的文章和一些想要写的文章目录如下: #1.Java Java 解惑:Comparable ...

  9. Android进阶之路 - 代码规范

    后来 - 回头再看该篇的时候,发现当项目处于中后期的时候,命名规范还是不太严谨,扩展性有限,所以推荐各位可以借鉴阿里.美团.华为等大厂的命名规范 ~ 关于代码规范(主要针对Android),我于202 ...

最新文章

  1. 《扩展 jQuery》——6.3 总结
  2. tf.nn.embedding_lookup函数的用法
  3. python3 随机数函数
  4. CSS中盒模型的理解
  5. SQL SERVER 查询表的行数
  6. 让我们了解下什么是智能客服(问答)
  7. 如何实现一个HTML5 RPG游戏引擎——第五章,实现人物和人物特效
  8. 响应式Web设计:HTML5和CSS3实战 笔记
  9. 推荐10个非常不错的JavaScript移动开发框架
  10. 局域网文件共享手机访问电脑文件软件
  11. 国家软考--高级系统分析师证书
  12. 马斯克是全人类的?他旗下有9家公司,特斯拉被评为最没技术含量
  13. win7 OneNote不能登录一直登录
  14. 【C++】error: passing ‘const xxx’ as ‘this’ argument discards qualifiers
  15. Oracle number类型详解
  16. 【git】------git的基本命令 (此文章转载我的老师 Alley-巷子)
  17. 【R语言】常用基本函数
  18. 人工智能知识体系大全
  19. 记录写博文用到的一些工具
  20. Web大学生网页作业成品——仿腾讯游戏官网网站设计与实现(HTML+CSS+JavaScript)

热门文章

  1. 学以致用——命令行中使用Java模块化技术编译、打包、运行iKb知识库应用
  2. 论文阅读:Inferring the 3D Standing Spine Posture from 2D Radiographs
  3. 递归(6):小白上楼梯
  4. IPV4与IPV6的双栈配置
  5. 《异构信息网络挖掘: 原理和方法(1)》一导读
  6. java 分部类_C#综合揭秘——分部类和分部方法
  7. 人工神经网络拓扑结构,神经网络拓扑结构图
  8. docker与容器文件传输
  9. DataList控件与ItemTemplate的用法
  10. 微信订餐平台还有着独特的资源优势