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

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

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

[[204613]]

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

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

本篇是本系列的第二篇,之前已經(jīng)發(fā)布的文章,有興趣可以先看看。

Android 字體修改概述|開篇

一、開篇

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

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

二、加載一個 Typeface

Typeface 的細節(jié),要講內(nèi)容還是挺多的,切聽我細細道來。

2.1 通過 AssetManager 加載字體

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

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

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

繼續(xù)看看 createFromAsset() 的源碼。

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

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

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

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

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

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

2.2 通過文件路徑加載字體

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

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

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

2.3 通過字體名稱獲取字體

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

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

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

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

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

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

2.4 通過 Typeface 獲得一個新的 Typeface

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

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

三、Typeface 的其它細節(jié)

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

3.1 Typeface 的初始化

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

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

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

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

如果想要使用它,Typeface 也提供了對應(yīng)的方法。

3.2 Typeface 中的 Style

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

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

3.3 Typeface 中的 Native 方法

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

3.4 簡單了解一下 FontFamily

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

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

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

四、小結(jié)

到這里就已經(jīng)講解清楚 Typeface 的所有內(nèi)容,看完本篇文章心里也有底去使用 Typeface 了。

總結(jié)來說:

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

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

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

Typeface 內(nèi)部最終調(diào)用的都是 native 方法,所以也不存在什么效率的問題。


【本文為51CTO專欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請通過微信公眾號聯(lián)系作者獲取授權(quán)】

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

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

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數(shù)據(jù)庫開源數(shù)據(jù)庫

2021-07-06 14:56:20

深度學(xué)習(xí)編程人工智能

2020-12-10 08:44:35

WebSocket輪詢Comet

2022-03-24 13:36:18

Java悲觀鎖樂觀鎖

2024-01-31 13:02:00

高并發(fā)熱點散列庫存分桶

2021-05-22 11:55:29

Python 開發(fā)編程語言

2020-02-10 14:26:10

GitHub代碼倉庫

2019-02-20 14:16:43

2024-04-11 12:19:01

Rust數(shù)據(jù)類型

2018-06-05 17:40:36

人工智能語音識別

2018-05-18 16:20:42

編程語言JavaPython

2018-12-20 11:20:47

物聯(lián)網(wǎng)設(shè)備物聯(lián)網(wǎng)

2021-12-27 18:00:30

對象數(shù)組Java

2018-08-20 08:29:18

2020-04-16 18:04:07

JavaScript前端技術(shù)

2018-10-30 10:53:42

路由器無線網(wǎng)絡(luò)無線路由器
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: a在线观看 | 亚洲视频中文字幕 | 一级欧美一级日韩片免费观看 | 欧美日韩一 | 欧美极品一区二区 | 欧美激情在线观看一区二区三区 | 久久免费国产 | av久久 | 日韩一区二区在线视频 | 久久久一二三 | 国产成人免费 | 国产成人综合在线 | 国产黄色大片 | 欧美一区2区三区4区公司二百 | 成人欧美一区二区三区白人 | 97国产精品| 蜜桃官网| 亚洲精品99999 | 精品久久一区二区三区 | 一级黄色片一级黄色片 | 久草在线 | 欧美一级做a爰片免费视频 国产美女特级嫩嫩嫩bbb片 | 免费久久网| 久久久久久久久久久久一区二区 | 日本a视频 | www.中文字幕.com | 97人人澡人人爽91综合色 | 在线观看黄色电影 | 中文二区| 最新高清无码专区 | 亚洲国产精品一区二区三区 | 亚洲视频免费 | av午夜电影 | 999久久久免费精品国产 | 在线观看av网站永久 | 国产日韩精品视频 | 精品日韩 | 91精品国产综合久久国产大片 | 黄色精品| 美日韩精品| 99精品一区二区三区 |