Android應用使用自定義字體的一些探究

2021-02-23 張濤的開源實驗室

最近團隊裡面在做程序界面統一的工作,因此希望統一字體,接到一個研究怎麼自定義字體的任務。因為我們的開發模式,所以需要研究在界面內的字體自定義,以及webview的顯示中的字體自定義。

android系統內置字體

android 系統本身內置了一些字體,可以在程序中使用,並且支持在xml配置textView的時候進行修改字體的樣式。支持欄位為android:textStyle ,android:typeface, android:fontFamily,系統內置了normal|bold|italic三種style, 內置了normal,sans,serif,monospace,幾種字體(實測這幾種字體僅英文有效),typace和fontFamily功能一樣。

使用自定義的字體

以上的方式可以改變字體的樣式,還不是真正的自定義。

android系統支持TypeFace,即ttf的字體文件。

我們可以在程序中放入ttf字體文件,在程序中使用Typeface設置字
體。

第一步,在assets目錄下新建fonts目錄,把ttf字體文件放到這。
第二步,程序中調用:

1

2

3

AssetManager mgr=getAssets();

Typeface tf=Typeface.createFromAsset(mgr, "fonts/ttf.ttf");

tv.setTypeface(tf);

注意ttf文件命名不能使用中文,否則可能無法加載。

對於需要使用比較多的地方,可以寫一個TextView的子類來統一處理。

在webview中使用自定義地體

對於本地的網頁,在asset目錄放字體文件,並在css中添加以下內容,自定義一個字體face,並且在需要的地方使用這個字體face即可。

1

2

3

4

5

6

@font-face {

font-family: "MyFont";

src: url('file:///android_asset/fonts/ttf.ttf');

}

h3 { font-family:"MyFont"}

對於在線的網頁,則需要把字體文件放到伺服器,使用同樣的方式定義字體face,應用到每個地方。

為了減少網頁或者說伺服器端的工作,可以使用本地注入的方式注入font-face的css,並對整個網頁進行樣式替換。

給webview自定義webViewClient,重寫onPageFinish,在其中添加如下內容:

1

2

3

4

5

view.loadUrl("javascript:!function(){" +

"s=document.createElement('style');s.innerHTML="

+ "\"@font-face{font-family:myhyqh;src:url('**injection**/hyqh.ttf');}*{font-family:myhyqh !important;}\";"

+ "document.getElementsByTagName('head')[0].appendChild(s);" +

"document.getElementsByTagName('body')[0].style.fontFamily = \"myhyqh\";}()");

由於網頁上是沒有權限訪問本地的asset文件夾的,因此我們需要攔截請求來加載本地的文件,我這裡替換了file:///android_assets/為 **injection**/了,我們還需要重寫
shouldInterceptRequest
在請求為我們這個字體文件的時候,加載本地文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@Override

public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

WebResourceResponse response = super.shouldInterceptRequest(view, url);

CLog.i("load intercept request:" + url);

if (url != null && url.contains("**injection**/")) {

String assertPath = url.substring(url.indexOf("**injection**/") + "**injection**/".length(), url.length());

try {

response = new WebResourceResponse("application/x-font-ttf",

"UTF8", getAssets().open(assertPath)

);

} catch (IOException e) {

e.printStackTrace();

}

}

return response;

}

問題

使用字體統一界面,但是也遇到了一些問題,如下:

運行速度變慢(毫秒級,用戶覺查不到),由於需要讀取自定義的字體文件,以及需要渲染,比使用系統字體要慢。

emoji在5.0以下的系統會有問題。

在網頁,如果採用伺服器文件的方法,會消耗用戶的流量

在網頁,採用本地注入方式,因為是在onpagefinish後才開始加載字體,因此頁面會重新渲染,影響效果。這樣還會造成網頁可能會出現樣式錯誤。

因為我們的程序中大量使用到emoji,以及考慮到性能的問題,決定還是使用系統自帶的字體了。

如果你在這方面有更好的方案,歡迎交流!



相關焦點

  • Android自定義性能高效的日曆控制項
    Android自定義優雅、性能高效的日曆控制項,完美支持周視圖,支持標記、自定義顏色、農曆等,任意控制月視圖顯示、任意日期攔截條件
  • 自定義字體@font-face的常見應用
    以下幾點請注意:1.因各瀏覽器對字體的兼容不同,需要同時備有多種字體樣式,請參考瀏覽器兼容情況;2.字體文件的路徑需要和網頁在同一域名下,否則需要做跨域處理;3.unicode-range設置只使用該字體的個別字符,有一定實用性,請參考文檔使用;本文列舉@font-face的常見應用。
  • Android精美日曆控制項CalendarView自定義使用完全解析
    UI,周視圖和月視圖可通過簡單自定義任意自由繪製,不怕美工提需求!!!下面教程將介紹如何實現3個API,自定義Canvas繪製日曆CalendarView的優勢:1、熱插拔設計,根據不同的UI需求完全自定義UI,簡單幾步即可實現,自定義事件日曆標記、顏色、農曆等2、完全Canvas繪製,性能和速度都很不錯,相比大多數基於GridView或RecyclerView實現的佔用內存更低
  • 自定義字體的引入方法
    應某人的要求寫一個關於自定義字體引入的方法,@font-face是css3中的一種規則。
  • Android 自定義權限真的安全嗎?
    一般來說,當我們需要在組件間跨應用通信時,我們都需要提供某種形式的權限驗證來保證通信安全。在 Android 上,我們通過在聲明組件時加入 android:permission 屬性來添加權限驗證,這裡的權限一般是用戶自定義權限。
  • 使用 Dagger 自定義 WorkManager
    https://developer.android.google.cn/topic/libraries/architecture/workmanager/https://developer.android.google.cn/jetpack/如果您一直關注本系列文章,則會發現我們已經討論過:在本篇文章中,我們將會討論使用 Dagger 自定義配置相關的內容,包括:在我們的 WorkerFactory
  • Android中自定義進度加載工具類的使用
    集成這裡使用MaterialProgressBar,關於這個開源控制項的使用我在上一篇文章Android中加載進度條實戰簡述已經很詳細的講到過了,這裡就不再做過多說明,大家如果感興趣的可以自己去了解一下。
  • Android 自定義Dialog
    R.layout.dialog_course_record_txt, null, false); setContentView(view); } @Override public void show() { super.show(); /** * 設置寬度全屏,要設置在show的後面
  • Android 字體修改,所有的細節都在這裡 | 開篇
    新媒體管家序在 Android 下使用自定義字體已經是一個比較常見的需求了
  • 打造 Material 字體樣式主題
    /   概述   /使用 Material 主題 (Theming) 自定義 Material 組件,目的是讓組件觀感與品牌保持一致。Material 主題包括 顏色、字體 和 形狀 參數,您可以對這些參數進行調整來獲得近乎無限的組件變體,同時保持其核心結構和易用性。
  • 超簡單實現Android自定義Toast
    Bamboy的自定義Toast,(以下稱作「BToast」)特點在於使用簡單,並且自帶兩種樣式:1)普通的文字樣式;2)帶圖標樣式。其中圖標有√和×兩種圖標。看效果先:簡單三步,我們現在就開始自定義一下吧!(一)、Layout:要自定義Toast,首先我們需要一個XML布局。但是在布局之前我們需要三個資源文件,分別是背景、√和×。背景可以用XML畫出來:toast_back.xml<?
  • Android自定義鍵盤之漢字鍵盤
    它裡面有很多方法,在我們自定義的軟鍵盤很多屬性,就需要我們用這個類來設置。比如:了解一些源碼,就可以是我們知道我們為什麼要這樣寫,為什麼要這樣做了!Key元素通過一些屬性來定義每個按鍵,下面是一些常用的屬性介紹: Codes:代表按鍵對應的輸出值,可以為unicode值或者逗號(,)分割的多個值,也可以為一個字符串。在字符串中通過「\」來轉義特殊字符,例如 『\n』 或則 『\uxxxx』 。
  • Android Studio自定義加固插件
    目錄前言平時我們打包生成apk後可能需要進行加固,如果每次手動去打開加固軟體然後再去加固非常的麻煩,因此我們可以通過自定義 -login <username> 首次使用必須先登錄
  • Android Studio 自定義Gradle Plugin
    在此之前我們先來了解下 Gradle插件 與 Gradle 的關係:Gradle插件 版本在項目根目錄下的 build.gradle 中,如下:dependencies { classpath 'com.android.tools.build:gradle:2.3.0'}而每個Gradle插件版本號又對應有一個或一些
  • Android 自定義 View 三步驟
    自定義 View 三步驟自定義View三步驟,即:onMeasure()(測量),onLayout()(布局),onDraw()(繪製)。onMeasure()首先我們需要弄清楚,自定義 View 為什麼需要重新測量。
  • 教程 | 如何在 Kindle 中自定義字體
    Kindle 設備自 5.9.6 版本固件開始支持自定義字體,實現方法也很簡單,只需要把自己喜歡的字體的文件拷貝到 Kindle 中,即可在閱讀電子書時輕鬆選用
  • 自定義 WorkManager —— 基礎概念
    https://developer.android.google.cn/topic/libraries/architecture/workmanager/https://developer.android.google.cn/jetpack/目前為止本系列已經討論過:在本篇文章中,我們將會討論自定義配置相關的內容,包括:本系列的下一篇文章將對依賴注入和 Dagger 展開討論
  • 聊一聊Android中的字體適配
    所以可以猜到微信的字體適配是如下方式實現的:字體大小不隨系統改變想要實現字體大小不隨系統改變有兩種方式:1. xml方式TextView 的字體單位不使用 sp,而是用 dp。因為 sp 單位的字體大小會隨系統字體大小的改變而改變,而 dp 單位則不會。2.
  • Android自定義toast實現懸浮通知效果
    Android通過toast實現懸浮通知效果,如圖:實現的功能:自定義懸浮彈窗;點擊其他地方該布局不受影響
  • 自定義CheckBox樣式
    二、自定義選擇器效果三、自定義素材四、為CheckBox標籤自定義樣式Android中自帶的CheckBox 樣式比較醜,為了美化CheckBox可使用一下方法。-- 自定義CheckBox 樣式 --> <style name="CustomCheckboxTheme" parent="@android:style/Widget.CompoundButton.CheckBox"> <item name="android:button">@drawable/custom_checkbox_selector