成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

想修改 Android 字體,你需要先了解一下 Typeface!!!

企業動態
本文就單獨來分析 Typeface 的一些源碼細節,本文在本系列中,可能相對枯燥一些,但是我覺得它又是不可或缺的一部分,所以單獨拿出一篇文章來細細說它。

[[204613]]

在 Android 下使用自定義字體已經是一個比較常見的需求了,最近也做了個比較深入的研究。

那么按照慣例我又要出個一篇有關 Android 修改字體相關的文章,但是寫下來發現內容還挺多的,所以我決定將它們拆分一下,分幾篇來詳細的講解(可能是五篇)。主要會是一些常用的替換字體的方案,***還會介紹一些全局替換的方案,當然也會包含***的 『Fonts in XML』的方案。

本篇是本系列的第二篇,之前已經發布的文章,有興趣可以先看看。

Android 字體修改概述|開篇

一、開篇

如果你想要操作字體,無論是使用 Android 系統自帶的字體,還是加載自己內置的 .ttf(TureType) 或者 .otf(OpenType) 格式的字體文件,你都需要使用到 Typeface 這個類。

本文就單獨來分析 Typeface 的一些源碼細節,本文在本系列中,可能相對枯燥一些,但是我覺得它又是不可或缺的一部分,所以單獨拿出一篇文章來細細說它。

二、加載一個 Typeface

Typeface 的細節,要講內容還是挺多的,切聽我細細道來。

2.1 通過 AssetManager 加載字體

一般我們會將需要的內置字體文件,放在 assets 目錄下面,之后就可以通過 Typeface.createFromAsset() 方法,獲得一個 Typeface 對象。

例如,現在在項目的 assets/fonts 目錄下,放一個字體 .ttf 文件。

然后,我們就可以在需要的時候加載它,這也是一段比較常見的代碼。

繼續看看 createFromAsset() 的源碼。

代碼很簡單,邏輯也很清晰。

首先會有判斷 sFallbackFonts 不能為 null ,否則直接拋出異常,sFallbackFonts 不是重點,這個之后再講。

它依賴 sDynamicTypefaceCache 來保證線程的安全。并且會使用 createAssetUid() 來獲取到這個字體的唯一 key ,通過這個唯一 key ,從 sDynamicTypefaceCache 中獲取已經被加載過的字體,如果沒有的話,再創建一個 FontFamily 的對象,通過 FontFamily.addFontFromAsset() 方法,將這個字體文件加入進去,***通過 createFromFamiliesWithDefault() 中,直接創建一個字體,最終存放到 sDynamicTypefaceCache 中去做一道緩存。

createFromFamiliesWithDefault() 方法需要傳遞一個 FontFamily 的數組,它本身也只是將這些 FontFamily 所代表的共性提取出來,最終調用 nativeCreateFromArray() 這個 native 的方法,所以效率上應該不會有太大的問題。

這也說明,其實放在 assets 目錄下的字體,只要通過 Typeface 加載過之后,它本身就會有一道緩存,之后再取也只是從緩存中獲取,并不會影響性能。

而 sDynamicTypefaceCache 是一個基于 Lru 算法的,***存儲 16 個字體的一個緩存。

2.2 通過文件路徑加載字體

Typeface 除了可以從 assets 目錄下,加載字體文件,它還可以加載其它地方存儲的字體文件,并提供了方便的 Api。

最終也是通過字體文件的絕對路徑進行加載,這部分邏輯也很好理解。一樣是使用到了 FontFamily ,一樣是使用到了 createFromFamilyWithDefault()。

這些并沒有用到什么新的內容,就不再展開細說一遍了。

2.3 通過字體名稱獲取字體

我們知道,Typeface 還可以管理一些 Android 系統自帶的字體,這些字體,如果想要獲取,也可以通過 Typeface 來加載,只需要傳遞進去對應的名稱即可。

可以看到,它除了需要傳遞一個 familyName 之外,還需要傳遞一個 style ,這里的 style ,就是之前說的 android:textStyle 傳遞的值,用于設定字體的粗體(bold)、斜體(italic)等參數的。

這個方法,其實最終調用的是另外一個 create() 方法的重載,這個方法后面會詳細講解到。將它單拎出來講解,是因為它其中涉及到一個 sSystemFontMap 對象。

sSystemFontMap 是在 Typeface 的初始化方法 init() 中進行初始化的。

可以看到,它實際上是通過 getSystemFontConfigLocation() 中,讀取到本地支持的字體文件,然后將它們一次性加載進行,供后面直接使用。

秉承了 Linux 的傳統,所有的配置都寫在文件里,這里也是直接從文件里讀取,getSystemFontConfigLocation() 方法獲取到的只是一個配置的路徑,最終讀取的是 FONTS_CONFIG 配置的 fonts.xml 文件。

2.4 通過 Typeface 獲得一個新的 Typeface

到這里,該講到前面提到的 create() 方法了,這里需要傳遞進來一個 Typeface 對象,并通過設置 style,為這個原始的 Typeface 字體類附加新的效果。

而這個過程也是不需要我們額外關心效率的問題的。它也提供了一個 sTypefaceCache 的緩存,來緩存我們曾經使用的的系統默認字體。

三、Typeface 的其它細節

到這里基本上就已經講解清楚 Typeface 的使用了,但是還有一些其它的細節,可以單獨拎出來進行額外的講解。

3.1 Typeface 的初始化

Typeface 的初始化,是放在靜態代碼塊中的,它會初始化一些我們常用的系統默認字體,存儲起來方便我們使用。

這里會先調用 init() 方法,加載系統自帶的字體,然后再初始化一系列,例如 DEFAULT 、SNAS_SERIF 等自帶字體。

所以如果我們只是需要獲取一個系統自帶的字體,直接使用這里初始化的一些常量字體即可。

它還會將 DEFAULT 字體,默認初始化一個 sDefaults 的數組,在其中幫我們預加載好粗體、斜體等常用的 Style。

如果想要使用它,Typeface 也提供了對應的方法。

3.2 Typeface 中的 Style

前面一直有提到一個 Style 的概念,它是可以通過 android:textStyle 屬性設置的,包括粗體、斜體等樣式。

在 Typeface 中,這些樣式也對應了一個個的常量,并且 Typeface 也提供了對應的 Api,讓我們獲取到當前字體的樣式。

3.3 Typeface 中的 Native 方法

在 Typeface 中,所有最終操作到加載字體的部分,全部都是 native 的方法。而 native 方法就是以效率著稱的,這里只需要保證不頻繁的調用(Typeface 已經做好了緩存,不會頻繁的調用),基本上也不會存在效率的問題。

3.4 簡單了解一下 FontFamily

FontFamily 在前面很多方法內都用到了。它實際上就是去讀取字體文件的數據流,然后再通過 native 方法去加載字體。

拿 addFont() 方法舉例,它會先獲取 FileInputStream 對象,轉換成一個 ByteBuffer 然后傳遞給 native 方法 nAddFont() 來加載字體。

這個對象,了解一下就可以了,沒有什么太復雜的邏輯。

四、小結

到這里就已經講解清楚 Typeface 的所有內容,看完本篇文章心里也有底去使用 Typeface 了。

總結來說:

Typeface 提供了一系列的 createXxx()方法,用于從不同的地方加載字體。

Typeface 支持從系統默認字體、字體文件以及 assets 目錄下,加載字體。

Typeface 本身已經支持字體緩存,我們只需要放心使用,不需要自身再額外緩存一遍。

Typeface 內部最終調用的都是 native 方法,所以也不存在什么效率的問題。


【本文為51CTO專欄作者“張旸”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2013-09-13 09:31:09

MongoDBZardosht KaTokutek

2022-08-25 14:42:45

JavaScrip字符串

2019-11-07 15:20:07

JavaCollectorsteeing

2022-09-23 15:01:33

圖片加載代碼

2023-05-09 08:25:26

Gaussdb數據庫開源數據庫

2021-07-06 14:56:20

深度學習編程人工智能

2020-12-10 08:44:35

WebSocket輪詢Comet

2022-03-24 13:36:18

Java悲觀鎖樂觀鎖

2021-05-22 11:55:29

Python 開發編程語言

2024-01-31 13:02:00

高并發熱點散列庫存分桶

2020-02-10 14:26:10

GitHub代碼倉庫

2019-02-20 14:16:43

2018-06-05 17:40:36

人工智能語音識別

2024-04-11 12:19:01

Rust數據類型

2018-05-18 16:20:42

編程語言JavaPython

2021-12-27 18:00:30

對象數組Java

2018-12-20 11:20:47

物聯網設備物聯網

2018-08-20 08:29:18

2020-04-16 18:04:07

JavaScript前端技術

2018-10-30 10:53:42

路由器無線網絡無線路由器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜看电影在线观看 | 一区二区在线 | 亚洲男女视频在线观看 | 毛片a级| 久久精品亚洲精品国产欧美 | 久久久一区二区三区 | 99精品欧美一区二区三区 | 天堂av在线影院 | 欧美午夜精品 | 成人小视频在线观看 | 亚洲精品专区 | 欧美成人精品激情在线观看 | 男女污污动态图 | 国产激情视频在线观看 | 97超碰站| 91精品久久 | 美女国产精品 | 久久久久久成人网 | 人成精品 | 国产精品国产成人国产三级 | 91精品国产一区二区三区 | 日本三级电影在线免费观看 | 91成人影院 | 精品粉嫩aⅴ一区二区三区四区 | 久久一区二区av | 国产免费av在线 | 一级a性色生活片久久毛片 一级特黄a大片 | 亚洲免费视频网址 | 国产一伦一伦一伦 | 99久久影院 | 亚洲高清在线 | 成人免费视频在线观看 | 国内精品久久精品 | 国产精品日韩欧美一区二区三区 | 亚洲一区二区三区在线 | 亚洲成人av | av一区二区三区 | 日韩精品一区二区三区在线播放 | 日韩欧美在线不卡 | 色精品| 一区影院 |