一、問題1:上一篇文章中對Activity進(jìn)行setFactory2的操作為什么能替代Fragment的setFactory2:
回答:首先Fragment的LayoutInflater是通過onGetLayoutInflater方法獲得的,那么看源碼是怎么調(diào)用的:


我們看看源碼中的“mHost”是什么呢?mHost是FragmentHostCallback,這個可以通過FragmentActivity的源碼查看它的賦值:



從這里可以看到它還是調(diào)用了父類的LayotuInflater的構(gòu)造,然后跟Activity使用的是同一個Factory,所以給Activity設(shè)置了Factory,那么就相當(dāng)于給Fragment設(shè)置了Factory。
二、問題2:頂部的StatusBar和底部的NavigartionBar如何換膚?
先上一張手機(jī)顏色分布圖:

可以看到頂部的StatusBar是由colorPrimaryDark 和 statusBarColor兩個顏色值共同控制,當(dāng)然statusBarColor的優(yōu)先級要高于colorPrimaryDark。
代碼中我們需要在兩個地方去設(shè)置這個顏色,第一個就是在ActivityLifecycleCallbacks里面的監(jiān)聽Activity的onCreate方法里面去設(shè)置;另外一個是在當(dāng)收到換膚通知的時候設(shè)置:
統(tǒng)一有個工具類寫下功能:

三、問題3:如何實現(xiàn)字體換膚?
步驟1):
在母包中的style.xml中定義一個skinTypeface的屬性:

在母包中的strings.xml中定義兩個空的字符串(占坑使用):

步驟2):
護(hù)膚apk中,將換膚的字體ttf格式,放到assets的font目錄下:

同樣在換膚apk的strings.xml中定義typeface:

步驟3):
換膚依賴庫中,在attrs.xml中定義skinTypeface:

經(jīng)過了前面的幾步,我們就能獲得換膚apk中的字體相關(guān)的Typeface:

接下來同樣也要在兩個地方加入獲得的Typeface,一個是ActivityLifecycleCallbacks的onCreate方法;另一個是在收到換膚通知之后再去設(shè)置typeface,最終傳遞到SkinAttribute類中處理,因為該類可以拿到所有需要換膚的View,我們只需要這個View是不是TextView的類型,就可以開啟換膚:

四:問題四:如何只替換指定的TextView的字體?
在問題三中,我們可以對所有的TextView進(jìn)行更換字體,那么產(chǎn)品要求說只是更換某些字體呢?
也很簡單, 在母包的xml中,將需要指定換字體的view增加一個skinTypeface這個屬性:

然后在SkinAttribute中找到這個屬性:

五:問題五:如何將自定義View動態(tài)換膚?
因為自定義View有很多的自定義屬性,所以我們沒法捕捉到全部的屬性,這里我們可以在換膚依賴包里面定義一個自定義view的公共接口:SkinViewSupport:

然后在母包的自定義View中,去實現(xiàn)這個接口:

在SkinAttribute中采集這些自定義View:

然后在開始換膚的時候,通知接口回調(diào):

最后母包中的自定義view,收到接口回調(diào)后,開始換膚:
