粗暴的方式,替換全局字體

在 Android 下使用自定義字體已是一個比較常見的需求了,最近也作了個比較深刻的研究。函數

那麼按照慣例我又要出個一篇有關 Android 修改字體相關的文章,可是寫下來發現內容還挺多的,因此我決定將它們拆分一下,分幾篇來詳細的講解(多是五篇)。主要會是一些經常使用的替換字體的方案,最後還會介紹一些全局替換的方案,固然也會包含最新的 『Fonts in XML』的方案。佈局

期待你持續關注。性能

本篇是本系列的第三篇,以前已經發布的文章,有興趣能夠先看看。字體

1、前言

前面已經分析了修改字體的全部細節,以及與修改字體相關的 Typeface 類,接下來就開始討論如何修改全局字體。spa

本篇會先介紹兩種比較粗暴的方式來修改全局的字體。設計

2、自定義字體相關的控件類

在開始一個新的項目的時候,通常習慣好點的都會定義一個 BaseActivity 和 BaseFragment 來做爲頁面的基類,這樣能夠方便咱們在以後的時候,對全部頁面增長一些統一的邏輯。3d

不過應該不會有人提早想到要給全部的控件,提早定義一個自定義的控件實現。code

可是若是在開發的初期,就已經考慮到字體須要修改的狀況的話,是能夠重寫一些字體顯示相關的控件。來達到全局替換字體的做用的。xml

Android 中,最經常使用的用來顯示字體的控件,就是 TextView,這裏就重寫一個 TextView 來達到替換字體的效果。對象

在 TextView 中,能夠經過 setTypeface() 方法,爲 TextView 設置一個字體,setTypeface() 方法有兩個重載方法,無非就是多傳遞了一個須要設置的 textStyle,用來標記粗體和斜體。

/f-setTypeface.png

其實最終都是調用一個參數的 setTypeface(,它纔是設置的關鍵。

/f-setTypeface1.png

能夠看到,設置字體其實是操做的 mTextPaint,mTextPaint 是 TextPaint 類的對象,直接繼承自 Paint,就是一個用來繪製文字的畫筆。

那麼,咱們就能夠直接自定義一個 TextView ,在構造函數中,經過 setTypeface() 方法,來修改 TextView 的字體。

主要代碼以下:

/f-fontTextView.png

注意,這裏還須要考慮在佈局中,爲咱們設定的 FontTextView 設置的 textStyle 屬性,多是粗體或者斜體。

一般設計師爲了考慮 App 的 UI 統一性和協調性,通常都會選用一個字體,因此將須要替換的字體封裝在 FontTextView 中,也沒有什麼大的問題。

那麼來驗證看看實現出來的效果,這裏專門選擇了一個比較特殊的字體。在佈局 xml 文件中,添加三個 FontTextView。

/f-fontxml.png

再來看看運行的效果。

/f-fontimage.png

這裏也考慮了在佈局中設置的 textStyle,而且一個已經比較傾斜的字體,使用 italic 標記以後,更傾斜了。

這個方法,若是在開發初期,還能夠接受,無非就是寫佈局的時候,須要注意使用自定義的控件,同時還除了 TextView ,還須要重寫 Button、EditText 等一系列須要顯示文字的控件,說到底仍是有點麻煩的。

並且若是是在一個已經成熟的項目上再使用這種方案,改動起來仍是很費勁的,基本上就是一通文本替換,改動會比較大一些。

3、遍歷 ViewTree,替換字體

在 Android 中,用於顯示文本的控件,都是直接或者間接集成自 TextView 的,那麼咱們只須要找一個合適的時機,遍歷佈局的 ViewTree,將其中全部 TextView 的子類都獲取出來,而後批量修改它們的字體,一樣也能夠達到全局替換的效果。

/f-replaceroot.png

在這個 replaceCustomFont() 的方法裏,回去判斷是否繼承自 TextView,若是是就替換字體。若是不是,再判斷是不是一個 ViewGroup,若是是的話,從其內取出全部的子 View,再遞歸調用 replaceCustomFont() 方法。

一般,爲了在合適的時機修改字體,咱們能夠將這個方法加在 Activity.onCreate() 方法,或者 Fragment.onCreateView() 方法的後面,修改的地方,相對少一些,不過還須要考慮 ListView、RecyclverView 這種動態生成 View 的邏輯,也須要注意不能遺漏。

舉個例子,寫一個佈局,在 Activity.onCreate() 方法中,調用 replaceCustomFont() 方法。

/f-replascemain.png

最後展示的效果以下。

/f-fontimage.png

使用這種方式,優勢是,不須要修改 XML 佈局,不須要重寫多個控件。只須要在 Inflater View 的以後,調用一下 replaceCustomFont() 方法便可。

缺點也很是的明顯,每一個頁面都須要修改,有動態加載 View 的地方可能會被遺漏,改動相比較以前的方案,稍微少一點。而且違背了組件的設計原則,實現方式也略顯粗暴。同時它每次都會遞歸遍歷 ViewTree,性能上多少都會有點影響。

4、小結

本文介紹的幾個辦法,在實際開發中,可能也用不上。不過不影響咱們瞭解這樣的方法。

下期預告

到如今爲止,介紹的替換字體的方案,其實並不夠優雅。從下期開始,就會開始介紹一些更優雅的方式,在現有項目上,全局的替換字體的一些方案。期待你的持續關注。

公衆號二維碼.jpg

相關文章
相關標籤/搜索