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

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

1.typeface、fontFamily、textStyle介紹

1.typeface 字體

typeface 枚舉類型,值如下

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

sans 和 serif 介紹:
在西方國(guó)家羅馬字母陣營(yíng)中,字體分為兩大種類: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 新增,所以要使用低版本的兼容庫(kù) 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)新增,但是兼容庫(kù)已兼容到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,目前了解的國(guó)內(nèi)沒有,國(guó)外的只有Google Play Services(版本11及以上),由于目前國(guó)內(nèi)很少安裝Google Play Services,所以國(guó)內(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 生成的字體使用了兼容庫(kù),已兼容低版本;證書的生成由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)建可下載字體

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

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

    @Override
    public void onTypefaceRequestFailed(int reason) {

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

Demo github地址: Downloadable Fonts sample app

總結(jié):

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 版權(quán)聲明:本賬號(hào)發(fā)布文章均來自公眾號(hào),承香墨影(cxmyDev),版權(quán)歸承香墨影所有。每周會(huì)統(tǒng)一更新到這里,如果喜...
    承香墨影閱讀 3,252評(píng)論 0 10
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評(píng)論 25 708
  • 在Android實(shí)際開發(fā)中根據(jù)UI的設(shè)計(jì)圖,經(jīng)常要去改變系統(tǒng)默認(rèn)的字體樣式這樣做會(huì)使apk變大很多啊而且為什么an...
    代碼打志bin閱讀 36,088評(píng)論 3 22
  • 擇日不如撞日,每天都想著要進(jìn)步,卻從未付諸行動(dòng),S君的《刻意學(xué)習(xí)》從7月24日購(gòu)買至今,仍然未讀,自己就像是松鼠一...
    Y伊歆Y閱讀 490評(píng)論 2 3
  • 萬物復(fù)蘇的春天嘩啦啦來了
    卡卡在海邊閱讀 169評(píng)論 0 0

友情鏈接更多精彩內(nèi)容