怎樣“無痛”全域性替換字型
序在 Android 下使用自定義字型已經是一個比較常見的需求了,最近也做了個比較深入的研究。 那麼按照慣例我又要出個一篇有關 Android 修改字型相關的文章,但是寫下來發現內容還挺多的,所以我決定將它們拆分一下,分幾篇來詳細的講解。主要會是一些常用的替換字型的方案,最後還會介紹一些全域性替換的方案,當然也會包含最新的 『Fonts in XML』的方案。 期待你持續關注。 本篇是本系列的第六篇,之前已經發布的文章,有興趣可以先看看。
一、前言上一篇講解了通過替換 AppCompatDelegate 來達到替換控制元件的目的,從而替換成我們需要的可設定自定義字型的控制元件,來達到替換字型的目的。 現在大多數人應該看出來了,到最後實現的目標就是如何快速、低入侵的替換全域性控制元件,然後對這些控制元件進行重寫,就可以達到我們很多的目的。換字型只是這其中的一種應用,還有其它的,例如:換膚、無痕埋點等等,都是有可借鑑的地方的。 本文再介紹一種方式,通過 接下來開始介紹所有的技術細節。 二、setFactory()2.1 setFactory() 的技術原理 對大家而言,LayoutInflater 應該是不陌生的,所有需要動態載入 layout-xml 中的 View 的地方都需要用到它的 而本文需要用到的是它另外兩個 Api 方法, /setFactory.png
這兩個方法分別接收 Factory 和 Factory2 ,它們兩個都是 Interface。並且這兩個方法的功能也是類似的。只是 不過一般而言,我們也不需要直接使用它。我們需要只用 Support.v4 包中,為我們提供的 LayoutInflaterCompat 這個相容類來做處理。和所有的相容類一樣,它其中會有一個 IMPL的變數,會根據不同的 Api Level 初始化不同的例項。 /compatImpl.png
可以看到,這裡只對 Api Level 21 作為一個分界,去處理邏輯,其中會有不同的實現,這裡有興趣可以一探究竟,有時間會單獨出一篇文章來講解,這裡就不再深入了。 這裡,我們需要用到 /impl-setfactory.png
可以看到, /LayoutFactory.png
我們這裡主要的功能,就在於實現 2.2 舉個例子對著原始碼說太乾了。下面我舉個實際的例子,相信就可以說明問題了。 首先我新建一個 Activity,在 /setfactory-javacode.png
再宣告一個佈局,讓它去顯示 layout-XML 佈局,層級很簡單,就是一個 LinearLayout 中間包含了一個 TextView。 然後,我們執行起來看看輸出的 Log ,這裡撇開了 DecorView 等這些佈局的列印,只看關鍵部分。 /setFactory-log.png
從 Log 輸出可以看出,實際上,你所有佈局的控制元件,都會經過 並且 三、利用 LayoutInflater 替換字型既然原理都清楚了,那麼我們接下來就開始實際操作一下,如何通過替換 LayoutInflaterFactory 來達到替換控制元件,從而達到替換字型的目的。 首先,定義一個 Activity 為基類,其中在 /demo-activitycode.png
CustomFontCompatDelegate 的實現,也非常的簡單,只需要在它的 /demo-delegate-code.png
其實,所有替換字型的邏輯,都在 FontTextView 中,接下來我們再看看 FontTextView 的邏輯。 /fontTextView.png
可以看到,在 FontTextView 中,直接完整的將字型替換成我們在 assets 目錄下存放的 到這裡就完成了基本的功能,我們接下來看看如何使用它。 只需要使用一個 Activity ,繼承我們剛才實現的 CustomFontActivity,然後寫一個簡單的佈局,其中有三個 TextView。 /demo-activityxml.png
最後,我們再來看看執行後的效果。 /f-fontimage.png
四、小結 到這裡基本上就介紹清楚如何通過 但是實際開發過程中,依然需要考慮所有可以顯示文字的控制元件,例如:TextView、EditText、Button 等等,這些都是我們需要重寫的控制元件。 |