Android中,粗暴的方式,修改字體


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

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

期待你持續關注。

本篇是本系列的第三篇,之前已經發布的文章,有興趣可以先看看。

一、前言

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

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

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

在開始一個新的項目的時候,一般習慣好點的都會定義一個 BaseActivity 和 BaseFragment 來作為頁面的基類,這樣可以方便我們在之后的時候,對所有頁面增加一些統一的邏輯。

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

但是如果在開發的初期,就已經考慮到字體需要修改的情況的話,是可以重寫一些字體顯示相關的控件。來達到全局替換字體的作用的。

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 等一系列需要顯示文字的控件,說到底還是有點麻煩的。

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

三、遍歷 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,性能上多少都會有點影響。

四、小結

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

下期預告

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

公眾號二維碼.jpg


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM