Android 夜間模式 換膚

本文為原創,轉載請注明出處。
文章標題為夜間模式,其實我這里想說的不是什么夜間模式,而是Skin庫,有了Skin庫,分分鐘實現換膚那是小Case,并且也能分分鐘實現換膚功能。當然還是那句話,說的那么屌,沒圖談個幾把,所以還是上個圖說話:

簡單介紹下圖片內容:我在apk中內置了普通模式和夜間模式兩套值,并且外置皮膚中也內置了普通模式和夜間模式。

ezgif-3-d97abc2e86.gif

本文為發布在Github上Skin庫的Wiki,實現了Android開發中換膚的功能,歡迎各位Star。以下為Wiki內容:

說在前面的

Skin的快速使用這篇文章介紹了如何快速使用本庫達到換膚,基本滿足了日常的換膚需求。本篇文章著重介紹Skin庫的特點。

換膚要求

不管你是準備在新工程中還是在已有工程中使用換膚功能,唯一的要求都需要你對需要換膚的資源進行規范的管理,這個規范的管理指資源的命名/分類。命名指資源的名字具有一定的規范而不是隨意的命名,分類指你能夠清除的知道哪些資源你是需要用于換膚的。
不管你使用何種換膚方式即使不適用Skin,這個規范都是極其重要的,切記。

Skin詳細介紹

1. 屬性解析工廠SkinAttrFactory

屬性解析工廠描述了如何以什么規則去解析目標屬性,也就是什么屬性才認為是需要進行換膚的屬性。Skin提供了兩個屬性解析工廠的實現:前綴屬性解析和標記屬性解析。屬性解析工廠是整個Skin中的主要組件之一。目前屬性解析工廠支持解析style(eg: style="@style/xxx")和引用屬性(eg: android:background="@drawable/xxx",不支持值類型(eg: android:background="#ffffff")的屬性。

前綴屬性解析工廠PrefixSkinAttrFactory

PrefixSkinAttrFactory解析屬性的規則是將包含有特定前綴的屬性解析出來,eg:skin_login_bg.jpgPrefixSkinAttrFactory會依次解析布局文件中的每一個View的屬性。

  • 前提:要求將工程中需要進行換膚的屬性都以固定的前綴開始命名,用戶可以設置任意的前綴,Skin默認以skin作為前綴。
  • 優點:因為是以前綴為規則區別換膚的屬性,因此這種方式對已具規模的工程要實現換膚功能來說用處大的多,因為可以做到只修改資源名字而不用去修改引用資源的地方(比如布局文件)就可以實現資源的整理,修改資源名字的時候記得一并修改引用。
  • 缺點:由于解析的時候會自動解析每一個布局文件中的元素,因此效率上不如接下來要講的標記屬性解析工廠。

標記屬性解析工廠NamespaceSkinAttrFactory

NamespaceSkinAttrFactory解析屬性的規則是將布局文件中添加了http://schemas.android.com/android/skin命名空間并且增加了標記的控件屬性解析出來。
eg:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
    ...
    xmlns:skin="http://schemas.android.com/android/skin"
...>
    <TextView
        ...
        skin:enable="true"
        ...
    />
</FrameLayout>
  • 前提:需要對進行換膚的控件增加標記。
  • 優點:由于只會解析包含了標記的控件,因此解析效率上會更高,對新工程來說采用這種方式會更好。
  • 缺點:由于需要打標記,因此對已具規模的工程帶來的勞力活會多一些。

可以擴展自己的屬性解析方式,只需繼承SkinAttrFactory即可。Skin默認配置標記屬性解析工廠,可以通過SkinManager改變配置。

相關Api

  • 創建前綴屬性解析工廠:SkinAttrFactory.createPrefixFactory(@Nullable String prefix)
  • 創建標記屬性解析工廠:SkinAttrFactory.createNamespaceFactory()
  • 更改屬性解析配置:SkinManager.setSkinAttrFactory(SkinAttrFactory factory)

2. 換膚屬性SkinAttr

SkinAttr定義了Skin支持的屬性描述。Skin默認實現了background,textColor,src三個屬性,通常這三個屬性已經滿足了大部分的控件屬性需求。
SkinAttrSupport用于管理SkinAttr,也就是說只有SkinAttrSupport中注冊了的屬性才會被屬性解析工廠關注,而不會去處理其它額外的屬性,默認注冊了SkinAttr的三個默認實現。

擴展自定義屬性支持

  1. 實現SkinAttr子類
    實現SkinAttr.apply(View)抽象方法,用于描述view如何使用屬性。
  2. 配置子類
    調用SkinAttrSupport.addSupportAttr(String attrName, SkinAttr skinAttr)方法即可添加自定義屬性。
    同樣SkinAttrSupport.removeSupport(String attrName)即可移除支持的屬性。

3. 換膚管理器SkinManager

SkinManager為整個換膚庫的管理器,主要處理皮膚的加載,更新以及通知監聽者刷新等。SkinManager需要在使用之前進行初始化,建議是在Application.onCreate()方法中進行初始化。
相關Api:

  • public void init(Context context)初始化
  • public boolean isUseSkin() 當前是否切換了皮膚
  • public void changeSkin(String suffix)通過后綴切換皮膚。
  • public void loadSkin(String skinPath, final SkinLoadListener listener)加載指定路徑的皮膚插件文件更換皮膚。
  • public void loadSkin(String skinPath, @Nullable final String suffix, final SkinLoadListener listener)加載指定路徑的皮膚插件文件更換皮膚,并指定文件中的皮膚屬性后綴。
  • public void addSkinChangedListener(SkinChangedListener listener)添加皮膚變化監聽
  • public void removeSkinChangedListener(SkinChangedListener listener)移除皮膚變化監聽
  • public void notifySkinChangedListeners()通知皮膚更新
  • public void setIgnoreWhenAttrNotFound(boolean ignore)設置資源未找到時是否忽略設置,默認為true
  • public void setSkinAttrFactory(SkinAttrFactory factory)設置屬性解析工廠,默認使用標記屬性解析工廠。

4. 界面換膚委托SkinDelegate

SkinDelegate包含了界面實現換膚所需要的處理。其主要功能是描述了控件的加載方式,以及界面中需要進行換膚的控件管理,以及相應的界面刷新等處理。
相關Api:

  • public void beforeCallSuperOnCreate()Activity調用super.onCreate()之前調用。用于設置界面的布局加載器LayoutInflaterFactory
  • public void afterCallSuperOnCreate()Activity調用super.onCreate()之后調用。用于切換狀態欄顏色等,建議使用我easy庫中的透明狀態欄實現。
  • public void onDestroy()ActivityonDestroy()方法中調用,用于移除界面刷新回調,以及資源回收等處理(暫無需要處理)。
  • public void setEnableSkinSwitchAnim(boolean mEnableSkinSwitchAnim)是否允許控件切換主題時使用動畫(默認Fade in),默認開啟。
  • public void setIsSkinSwitchAnimAlways(boolean mIsSkinSwitchAnimAlways)設置需要進行皮膚切換的view屬性沒有改變時是否也有動畫切換,默認為false

如果不想管理SkinDelegate,則可以使用BaseSkinActivity作為程序中Activity的基類,其代管了SkinDelegate的實現。
對于已具規模的工程,可能已經有自己的BaseActivity,則可以仿照BaseSkinActivity管理一個SkinDelegate即可。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,947評論 18 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,766評論 18 399
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,958評論 6 342
  • 前言: 本文主要講述如何在項目中,在不重啟應用的情況下,實現動態換膚的效果。換膚這塊做的比較好的,有網易云音樂,q...
    Yagami3zZ閱讀 13,725評論 5 51
  • 1 在微博上有很多人給我發私信講述自己的苦惱,訴說自己在學習、工作和感情中遇到的問題。 有時我會不太客氣地說,收起...
    遠近先生閱讀 873評論 2 8