玩转安卓字体
起因
最近公司有個(gè)需求,需要做 Widget ,內(nèi)心其實(shí)是拒絕的,因?yàn)檫@個(gè)玩意兒特別難用,而且限制重重,但沒辦法,也不能不做,那就開始吧。
本來以為挺簡單的東西,一個(gè)列表展示數(shù)據(jù),然后再展示一些基本數(shù)據(jù),兩天搞定,然后拿給 UI 去看,下面是和UI的對(duì)話。
UI:你照著藍(lán)湖做了嘛?
我:有啥問題嗎?(很納悶。。。我就是照著藍(lán)湖做的啊!)
UI:你看你這個(gè)時(shí)間的字體和我圖上的不一樣啊!
我:額。。。行吧,我回去想想辦法,你把字體發(fā)給我吧(內(nèi)心一萬只草泥馬走過。。。)
原生字體
很久沒搞過字體了,安卓系統(tǒng)一共為我們預(yù)制了四種字體,來看下吧:
來看個(gè)例子吧:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="Normal"android:textColor="#000"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:fontFamily="sans-serif"android:text="Sans"android:textColor="#000"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:fontFamily="serif"android:text="Serif"android:textColor="#000"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:fontFamily="monospace"android:text="Monospace"android:textColor="#000"android:textSize="30sp" /></LinearLayout>上面例子很簡單,一個(gè)線性布局包裹著上面描述的系統(tǒng)預(yù)制的四種字體,來看下效果圖吧:
其實(shí)并不是只能像上面這樣來進(jìn)行使用,上面的四種還可以進(jìn)行相互組合,也可以有不同的效果,大家可以自己試試:
字體并不是只能在布局文件中進(jìn)行修改,在代碼中同樣可以進(jìn)行修改:
//設(shè)置字體樣式 mainText.typeface = Typeface.SANS_SERIF mainText.typeface = Typeface.SERIF如果沒有什么特殊要求的話,上面的這幾種字體基本就能滿足大部分的開發(fā)需求了,而且還都可以對(duì)字體進(jìn)行加粗和斜體,就更能滿足了。
使用三方字體
但UI并不認(rèn)為安卓預(yù)制的幾種字體好看,就想弄點(diǎn)不一樣的字體😂,那也沒辦法,就來看看怎么設(shè)置吧。
引入字體
既然想使用三方字體,那第一步肯定是要引入下三方字體文件,字體文件后綴為 .ttf,需要將字體文件放到assets->fonts文件夾中,項(xiàng)目中沒有這個(gè)文件夾不要緊,自己新建一個(gè)即可。
使用
使用很簡單,通過AssetsManager就能獲取到字體文件,然后直接通過setTypeFace方法將字體設(shè)置下即可:
//從asset 讀取字體 根據(jù)路徑得到Typeface val tf = Typeface.createFromAsset(assets, "fonts/你的字體名稱.ttf") //設(shè)置字體 mainText.typeface = tf問題
至此為止,上面的內(nèi)容就是百度安卓字體能出來的內(nèi)容,但是!!!沒法用啊,文章開頭就說到了,我現(xiàn)在做的是 AppWidget 啊,限制非常多,只能通過 RemoteView 的一些固定方法來設(shè)置控件的值,但 RemoteView 中并沒有可以設(shè)置字體的方法,這該咋辦呢???
百度了半天也沒有找到結(jié)果,就想著能不能在 Application 中通過反射將 TextView 的字體中其中一個(gè)的默認(rèn)字體給修改成我想要的字體,然后通過設(shè)置主題的方法給 AppWidget 中的 TextView 進(jìn)行設(shè)置以來達(dá)到修改字體的結(jié)果。
先來寫下 Application 中的字體替換代碼:
class App : Application() {override fun onCreate() {super.onCreate()updateFont()}private fun updateFont() {val regular = Typeface.createFromAsset(assets,"fonts/你的字體名稱.ttf")replaceFont(regular)}@SuppressLint("DiscouragedPrivateApi")private fun replaceFont(newTypeface: Typeface) {val newMap: MutableMap<String?, Typeface> = HashMap()newMap["MONOSPACE"] = newTypefacetry {val staticField = Typeface::class.java.getDeclaredField("sSystemFontMap")staticField.isAccessible = truestaticField[null] = newMap} catch (e: Exception) {e.printStackTrace()}}}下面來在主題中設(shè)置下:
<!-- 字體 theme. --> <style name="FontAppTheme" parent="Theme.AppCompat"><item name="android:typeface">monospace</item> </style>之后就可以在 TextView 中進(jìn)行設(shè)置了:
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="12:34"android:textColor="#000"android:textSize="30sp"android:theme="@style/FontAppTheme" />解決方案
上面的這種方法太麻煩,而且還使用了反射,太不友好了。就想著去看看官方文檔吧,沒準(zhǔn)有什么好用的方法呢。
果然。。。。進(jìn)入官方文檔的第一句話就給我整笑了。。。
What?只需要像放圖片一樣在 res 中建一個(gè) font 文件夾,然后將字體放進(jìn)去,就可以像使用圖片一樣來使用字體了???
那我搞上面一堆干啥??
嗯。。。。遇到問題還是盡量少百度,多看官方文檔吧。。
而且動(dòng)態(tài)設(shè)置字體的時(shí)候也沒必要像之前那樣通過 AssetsManager 來獲取字體了,只需要通過 Resources 就可以獲取到了:
val tf = resources.getFont(R.font.myfont) mainText.typeface = tf這是字體官方文檔的地址:https://developer.android.google.cn/guide/topics/ui/look-and-feel/fonts-in-xml
總結(jié)
哎,其實(shí)很簡單的一個(gè)東西,而且在 Android 8.0 的時(shí)候就已經(jīng)實(shí)現(xiàn)的東西,現(xiàn)在馬上都 Android 12 了我竟然都不知道,慚愧啊!!!
好了,就這樣吧,大家以后遇到問題還是多看文檔吧。。。千萬不要學(xué)我。
總結(jié)
- 上一篇: 5大关键,让你二十年后依然是人才
- 下一篇: lodop直接打印服务器的文件,C-Lo