偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

[[204613]]

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

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

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

Android 字體修改概述|開篇

一、開篇

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

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

二、加載一個(gè) Typeface

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

2.1 通過(guò) AssetManager 加載字體

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

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

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

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

代碼很簡(jiǎn)單,邏輯也很清晰。

首先會(huì)有判斷 sFallbackFonts 不能為 null ,否則直接拋出異常,sFallbackFonts 不是重點(diǎn),這個(gè)之后再講。

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

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

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

而 sDynamicTypefaceCache 是一個(gè)基于 Lru 算法的,***存儲(chǔ) 16 個(gè)字體的一個(gè)緩存。

2.2 通過(guò)文件路徑加載字體

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

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

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

2.3 通過(guò)字體名稱獲取字體

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

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

這個(gè)方法,其實(shí)最終調(diào)用的是另外一個(gè) create() 方法的重載,這個(gè)方法后面會(huì)詳細(xì)講解到。將它單拎出來(lái)講解,是因?yàn)樗渲猩婕暗揭粋€(gè) sSystemFontMap 對(duì)象。

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

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

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

2.4 通過(guò) Typeface 獲得一個(gè)新的 Typeface

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

而這個(gè)過(guò)程也是不需要我們額外關(guān)心效率的問(wèn)題的。它也提供了一個(gè) sTypefaceCache 的緩存,來(lái)緩存我們?cè)?jīng)使用的的系統(tǒng)默認(rèn)字體。

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

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

3.1 Typeface 的初始化

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

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

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

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

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

3.2 Typeface 中的 Style

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

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

3.3 Typeface 中的 Native 方法

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

3.4 簡(jiǎn)單了解一下 FontFamily

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

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

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

四、小結(jié)

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

總結(jié)來(lái)說(shuō):

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

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

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

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


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

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

責(zé)任編輯:武曉燕 來(lái)源: 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

2023-05-09 08:25:26

Gaussdb數(shù)據(jù)庫(kù)開源數(shù)據(jù)庫(kù)

2022-09-23 15:01:33

圖片加載代碼

2021-07-06 14:56:20

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

2022-03-24 13:36:18

Java悲觀鎖樂(lè)觀鎖

2024-01-31 13:02:00

高并發(fā)熱點(diǎn)散列庫(kù)存分桶

2020-12-10 08:44:35

WebSocket輪詢Comet

2021-05-22 11:55:29

Python 開發(fā)編程語(yǔ)言

2024-04-11 12:19:01

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

2018-06-05 17:40:36

人工智能語(yǔ)音識(shí)別

2018-05-18 16:20:42

編程語(yǔ)言JavaPython

2020-02-10 14:26:10

GitHub代碼倉(cāng)庫(kù)

2019-02-20 14:16:43

2018-12-20 11:20:47

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

2021-12-27 18:00:30

對(duì)象數(shù)組Java

2020-04-16 18:04:07

JavaScript前端技術(shù)

2018-10-30 10:53:42

路由器無(wú)線網(wǎng)絡(luò)無(wú)線路由器

2022-03-07 06:34:22

CQRS數(shù)據(jù)庫(kù)數(shù)據(jù)模型
點(diǎn)贊
收藏

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