Android自定義字體設(shè)置

Android自定義字體設(shè)置

1.typeface、fontFamily、textStyle介紹

1.typeface 字體

typeface 枚舉類型碱璃,值如下

  • normal(默認(rèn)字體)
  • sans (無襯線字體)
  • serif(有襯線字體)
  • monospace(等寬字體)

sans 和 serif 介紹:
在西方國家羅馬字母陣營中,字體分為兩大種類:Serif和Sans Serif。
serif(有襯線字體):在字的筆劃開始及結(jié)束的地方有額外的裝飾作岖,而且筆劃的粗細(xì)會(huì)因直橫的不同而有不同。
sans serif(無襯線字體):沒有額外的裝飾五芝,筆劃粗細(xì)大致差不多

Sans-serif.jpg

monospace 介紹:
打字機(jī)體雖然也屬于Sans Serif痘儡,但由于是等寬字體,所以另外獨(dú)立出Monospace這一種類
monospace (等寬字體):指每個(gè)字符寬度都一樣枢步。優(yōu)點(diǎn)容易對(duì)齊谤辜,經(jīng)常用來顯示代碼。

2.fontFamily 字型家族

什么是字型家族价捧?它和typeface 的區(qū)別丑念?要想了解首先得了解下什么是 typeface、font
typeface:字體结蟋,是一個(gè)抽象的總體概念(它是一款“設(shè)計(jì)”)脯倚,例如:宋體、楷體
font:是指特定尺寸、特定字重推正、字偶間距等信息的一種 Typeface 的具體實(shí)現(xiàn)
fontFamily 是font的一個(gè)集合

使用提示可知 fontFamily 值如下

  • sans-serif
  • sans-serif-condensed
  • sans-serif-smallcaps
  • serif
  • serif-monospace
  • monospace
  • casual
  • cursive

3.textStyle 字體樣式

textStyle 標(biāo)記類型恍涂,值如下

  • normal(默認(rèn)字體)
  • bold (加粗)
  • italic(斜體)

4.三者關(guān)系

查看TextView源碼(API 27)可知:TextView構(gòu)造方法大致如下

public TextView(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes) {
    ...
    setTypefaceFromAttrs(fontTypeface, fontFamily, typefaceIndex, styleIndex);
    ...
}

setTypefaceFromAttrs方法

/**
 * 
 * @param fontTypeface 要設(shè)置的 Typeface
 * @param familyName 要設(shè)置的 fontFamily
 * @param typefaceIndex 要設(shè)置的 typeface
 * @param styleIndex 要設(shè)置的 style
 */
private void setTypefaceFromAttrs(Typeface fontTypeface,String familyName,
                                    int typefaceIndex,int styleIndex) {
    Typeface tf = fontTypeface;
    if (tf == null && familyName != null) {
        // 有fontFamily時(shí),用fontFamily
        tf = Typeface.create(familyName, styleIndex);
    } else if (tf != null && tf.getStyle() != styleIndex) {
        tf = Typeface.create(tf, styleIndex);
    }
    if (tf != null) {
        setTypeface(tf);
        return;
    }
    switch (typefaceIndex) {
        case SANS:
            tf = Typeface.SANS_SERIF;
            break;
    
        case SERIF:
            tf = Typeface.SERIF;
            break;
    
        case MONOSPACE:
            tf = Typeface.MONOSPACE;
            break;
    }
    // 其它都用typeface
    setTypeface(tf, styleIndex);
 }

總結(jié):

1.typeface植榕、fontFamily:都是設(shè)置字體再沧,都設(shè)置時(shí)優(yōu)先使用 fontFamily。
2.textStyle:設(shè)置字體的樣式

2.設(shè)置自定義字體

方式1:直接設(shè)置

1.把字體ttf文件放到assets/fonts目錄下尊残,沒有此目錄手動(dòng)創(chuàng)建


type1.png

2.設(shè)置

Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/aa.ttf");
textView.setTypeface(typeface);

3.優(yōu)化
使用優(yōu)化:繼承自TextView炒瘸,重寫getTypeface(),返回自定義typeface
typeface創(chuàng)建優(yōu)化:可用map封裝后進(jìn)行獲取寝衫,代碼略

Override
public Typeface getTypeface() {
   return Typeface.createFromAsset(getContext().getAssets(), "fonts/aa.ttf");
}

總結(jié):

適用于:指定TextView

方式2:反射設(shè)置

1.把系統(tǒng)的typeface替換為自定義的

Typeface typeFace = Typeface.createFromAsset(getAssets(), "fonts/aa.ttf");
try {
    // xml屬性值與Typeface屬性值對(duì)應(yīng)
    // normal      Typeface.DEFAULT
    // sans        Typeface.SANS_SERIF
    // serif       Typeface.SERIF
    // monospace   Typeface.MONOSPACE
   Field field = Typeface.class.getDeclaredField("SERIF" );
   field.setAccessible( true);
   field.set( null, typeFace );
} catch (NoSuchFieldException e) {
   e.printStackTrace();
} catch (IllegalAccessException e) {
   e.printStackTrace();
}

2.設(shè)置typeface值為 sans顷扩、 serif、 monospace其中一種慰毅,可在TextView隘截、Activity、Application里面的xml樣式里面設(shè)置

android:typeface="serif"

原理介紹:
1.xml設(shè)置完typeface為指定值后汹胃,最終xml會(huì)解析為代碼執(zhí)行(例如:設(shè)置android:typeface="serif"
最終會(huì)解析調(diào)用setTypeface(Typeface.SERIF))
2.預(yù)先把Typeface的某個(gè)系統(tǒng)字體通過反射強(qiáng)制替換自定義的Typeface(例如:把Typeface.SERIF強(qiáng)制替換為自定義的字體)
3.xml中設(shè)置typeface為已替換的字體即可(例如:android:typeface="serif")
舉例說明:例如:xml設(shè)置字體android:typeface="serif"婶芭,代碼設(shè)置的字體是Typeface.SERIF,可是Typeface.SERIF里面的內(nèi)容是強(qiáng)制替換后的自定義的字體
總結(jié):

適用于:App字體樣式不多的情況着饥,因?yàn)槟隳芴鎿Q的就SANS_SERIF犀农、SERIF、MONOSPACE這幾個(gè)值

方式3:fontFamily設(shè)置

1.把字體ttf文件放到res/fonts目錄下贱勃,沒有此目錄手動(dòng)創(chuàng)建或使用Android studio創(chuàng)建


type3.png

2.設(shè)置

1.TextView設(shè)置
android:fontFamily="@font/aa"
2.activity井赌、application樣式里設(shè)置
<item name="android:fontFamily">@font/aa</item>

3.兼容
因?yàn)?fontFamily API16 新增,所以要使用低版本的兼容庫 com.android.support:appcompat-v7:26.0.0 以上

1.TextView設(shè)置
app:fontFamily="@font/aa"
2.activity贵扰、application樣式里設(shè)置
<item name="fontFamily">@font/aa</item>

總結(jié):

適用于:各種情況

Demo github地址: devblog androidFont

3.設(shè)置下載字體(了解)

為什么要下載字體:最主要的原因就是可以減少apk的體積仇穗,因?yàn)樽煮w放到apk內(nèi)會(huì)增大apk體積,通過下載就不會(huì)戚绕。
使用范圍:此功能是Android 8.0(API26)新增纹坐,但是兼容庫已兼容到API14,所以可放心使用
原理:所有的app都可以從字體提供app(例如:Google Play Services)里獲取字體舞丛,字體提供app會(huì)把字體緩存到本地耘子,所以如果多個(gè)app用相同的字體,它們則會(huì)共用同一個(gè)字體文件球切,優(yōu)點(diǎn):減少手機(jī)內(nèi)存和磁盤空間谷誓,提高整體系統(tǒng)的運(yùn)行狀況。
使用前提:手機(jī)上必須有一個(gè)字體提供app吨凑,目前了解的國內(nèi)沒有捍歪,國外的只有Google Play Services(版本11及以上)户辱,由于目前國內(nèi)很少安裝Google Play Services,所以國內(nèi)此功能目前沒有用

方式1:Android studio創(chuàng)建可下載字體

Android studio 3.0及以上可下載糙臼,以下以Android studio 3.1.3介紹

1.選擇more Fonts

more.png

2.選擇創(chuàng)建可下載字體

select_font.png

3.點(diǎn)擊ok庐镐,則會(huì)在font目錄下創(chuàng)建對(duì)應(yīng)的字體xml配置文件,內(nèi)容如下:

xmlfont.png

創(chuàng)建證書文件font_certs.xml

font_certs.png

參數(shù)介紹:
fontProviderAuthority 字體提供app的權(quán)限
fontProviderPackage 字體提供app的包名变逃,用于獲取是哪個(gè)字體提供app
fontProviderQuery 字體提供app的字體名稱必逆,用于獲取是哪個(gè)字體
fontProviderCerts 字體提供app的證書
總結(jié):Android studio 生成的字體使用了兼容庫,已兼容低版本揽乱;證書的生成由Android studio 自動(dòng)生成名眉,不用管理

4.第3步點(diǎn)擊ok后,也會(huì)在AndroidManifest的application節(jié)點(diǎn)下生成如下內(nèi)容:

preload.png

創(chuàng)建預(yù)加載字體文件preloaded_fonts.xml

preload_fonts.png

介紹:以上是聲明使用預(yù)加載字體锤窑,如果沒有使用預(yù)加載字體璧针,則會(huì)在第一次設(shè)置可下載字體的時(shí)候嚷炉,會(huì)先下載字體然后設(shè)置渊啰,這樣會(huì)增加布局繪制時(shí)間,所以在AndroidManifest下聲明要預(yù)加載的字體申屹,則會(huì)在app啟動(dòng)時(shí)就加載即可解決這個(gè)問題绘证,如果下載出現(xiàn)超時(shí)或無網(wǎng)等失敗則會(huì)使用默認(rèn)字體

方式2:代碼創(chuàng)建可下載字體

以下使用了兼容庫,參數(shù)和上面一致

// 創(chuàng)建請求
FontRequest request = new FontRequest(
        "com.google.android.gms.fonts",
        "com.google.android.gms",
        query,
        R.array.com_google_android_gms_fonts_certs);
        
// 請求回調(diào)
FontsContractCompat.FontRequestCallback callback = new FontsContractCompat.FontRequestCallback() {
    @Override
    public void onTypefaceRetrieved(Typeface typeface) {
        // 成功
        mDownloadableFontTextView.setTypeface(typeface);
    }

    @Override
    public void onTypefaceRequestFailed(int reason) {

    }
};
// 請求
FontsContractCompat.requestFont(MainActivity.this, request, callback, getHandlerThreadHandler());

Demo github地址: Downloadable Fonts sample app

總結(jié):

適用于:不適用國內(nèi)

個(gè)人博客地址: devbolg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哗讥,一起剝皮案震驚了整個(gè)濱河市嚷那,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杆煞,老刑警劉巖魏宽,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異决乎,居然都是意外死亡队询,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門构诚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚌斩,“玉大人,你說我怎么就攤上這事范嘱∷蜕牛” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵丑蛤,是天一觀的道長叠聋。 經(jīng)常有香客問我,道長受裹,這世上最難降的妖魔是什么碌补? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上脑慧,老公的妹妹穿的比我還像新娘魄眉。我一直安慰自己,他們只是感情好闷袒,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布坑律。 她就那樣靜靜地躺著,像睡著了一般囊骤。 火紅的嫁衣襯著肌膚如雪晃择。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天也物,我揣著相機(jī)與錄音宫屠,去河邊找鬼。 笑死滑蚯,一個(gè)胖子當(dāng)著我的面吹牛浪蹂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播告材,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼坤次,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斥赋?” 一聲冷哼從身側(cè)響起缰猴,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疤剑,沒想到半個(gè)月后滑绒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隘膘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年疑故,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棘幸。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焰扳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出误续,到底是詐尸還是另有隱情吨悍,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布蹋嵌,位于F島的核電站育瓜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏栽烂。R本人自食惡果不足惜躏仇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一恋脚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧焰手,春花似錦糟描、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至躲履,卻和暖如春见间,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背工猜。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工米诉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人篷帅。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓史侣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親犹褒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抵窒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容