設(shè)計(jì)師說,我們要在 App 里用十種字體?。?!
序
在 Android 下使用自定義字體已經(jīng)是一個(gè)比較常見的需求了,最近也做了個(gè)比較深入的研究。
那么按照慣例我又要出個(gè)一篇有關(guān) Android 修改字體相關(guān)的文章,但是寫下來發(fā)現(xiàn)內(nèi)容還挺多的,所以我決定將它們拆分一下,分幾篇來詳細(xì)的講解。主要會(huì)是一些常用的替換字體的方案,最后還會(huì)介紹一些全局替換的方案,當(dāng)然也會(huì)包含最新的 『Fonts in XML』的方案。
期待你持續(xù)關(guān)注。
本篇是本系列的第六篇,之前已經(jīng)發(fā)布的文章,有興趣可以先看看。
修改字體需要了解 Typeface 的所有細(xì)節(jié)
利用 AppCompatDelegate ,全局替換全局字體
一、前言
之前寫了很多關(guān)于如何在成熟項(xiàng)目中,快速、低入侵的替換全局的字體。但是通常,如果設(shè)計(jì)師有替換字體的要求,一般不會(huì)只使用一個(gè)字體,而是會(huì)有多個(gè)不同的字體文件,根據(jù)不同的顯示位置,加載不同的字體文件。
那么本文,就介紹如何通過自定義屬性,來指定需要的字體,從而實(shí)現(xiàn)加載多字體文件的需求。
如何使用 LayoutInflater.setFactroy() 動(dòng)態(tài)替換控件,這是本文的基礎(chǔ),如果不太明白的可以先看看之前的文章《利用 LayoutInflater,優(yōu)雅的替換全局字體》。
二、自定義屬性
既然,我們已經(jīng)需要重寫 TextView、Button 這一系列顯示文字的控件,那么如何區(qū)分它們加載那個(gè)字體文件,我第一個(gè)想到的就是使用屬性來完成。
對(duì)于自定義屬性,其實(shí)用起來非常的簡(jiǎn)單,一般通過幾個(gè)步驟,就可以簡(jiǎn)單使用。
- 編寫自定義 View 類。
- 編寫 values/attrs.xml,編寫 styleable 或者 attr 標(biāo)簽。
- 在 layout-xml 布局中,使用自定義屬性。(需要注意 namespace)。
- 在自定義 View 中,通過 TypedArray 或者 AttributeSet 獲取到我們自定義的屬性。
其實(shí),自定義屬性非常的靈活,定義的時(shí)候可以選擇使用 declare-styleable 或者 attr 標(biāo)簽來定義它,而獲取的時(shí)候,也可以選擇使用 TypedArray 或者 AttributeSet 來獲取它。這些都非常的靈活,我們按照自己的需要設(shè)定和獲取就好了,沒什么好細(xì)說的,有關(guān)自定義屬性,可以單獨(dú)寫一篇文章了,就不在這里贅述了,有空再單獨(dú)總結(jié)。
三、使用自定義屬性的 Demo
既然已經(jīng)明確了方案,會(huì)使用 LayoutInflater.setFactory() 來替換 TextView 控件,在 TextView 控件中,通過獲取自定義屬性的值,拿到我們定義的數(shù)據(jù),根據(jù)自定義數(shù)據(jù)的值,為 TextView 加載不同的字體文件。
那么接下來就讓我們實(shí)際操作一下,看看如何實(shí)現(xiàn)吧。
3.1 準(zhǔn)備工作
首先我們需要有多個(gè)字體文件,這里把它存儲(chǔ)在 assets 目錄下面。
這里使用了 6 個(gè)不同的字體文件,它們是 .otf 格式的。
然后就可以編寫我們需要的自定義屬性了。
因?yàn)槲覀儽旧碜煮w有點(diǎn)多,所以這里使用了一個(gè)枚舉類型的 attr 來區(qū)分,為每種字體設(shè)置一個(gè)簡(jiǎn)稱,這樣可以簡(jiǎn)化我們后續(xù)的操作。
接下來就可以開始編寫我們的自定義 FontAppCompatText 了。
在 FontAppCompatText 中,從 AttributeSet 中,獲取到我們通過自定義屬性設(shè)定的字體,然后根據(jù)屬性設(shè)定字體,分別加載不同的字體文件。當(dāng)然你也可以用 TypedArray ,獲取的方式略有不同。
這里用到了 Typeface,它可以幫我們加載字體文件。如果不了解的,可以先看看之前的文章《想要修改 Android 字體,先了解一下 Typeface 吧》。
然后,我們還需要一個(gè) BaseActivity ,在其中的 onCreate() 方法中,調(diào)用替換控件需要的 LayoutInflaterCompat.setFratory() 方法。
到這里,前期的準(zhǔn)備工作就已經(jīng)做好了,我們只需要使用它們就好了。
3.2 使用屬性加載多字體
首先,我們需要有一個(gè) Activity,來繼承 CustomFontActivity 。
在其中加載的 layout-xml 布局中,寫很多個(gè) TextView ,分別使用我們之前自定義屬性 font ,來配置不同的字體。
需要注意的是,因?yàn)檫@里使用了自定義屬性,所以需要在根布局上,添加 xmlns:fonts="http://schemas.android.com/apk/res-auto"" ,一般 IDE 也會(huì)有警告,我們忽略它就可以了,使用 tools:ignore="MissingPrefix"設(shè)置忽略,當(dāng)然,這里由引入了 tools 這個(gè)命名空間,所以還需要加上 xmlns:tools="http://schemas.android.com/tools"。
到這里就已經(jīng)完成了我們使用自定義屬性,區(qū)分 TextView 加載不同的字體的要求了。
找個(gè)設(shè)備運(yùn)行一下,看看效果如何。
我這個(gè)字體文件,比較小,只包含了英文和數(shù)字,所以對(duì)中文無效。
【本文為51CTO專欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過微信公眾號(hào)聯(lián)系作者獲取授權(quán)】