天天看點

android換膚哪個簡單,Android一鍵換膚功能實作

市面上對數的App都提供換膚功能,這裡暫且不講白天和夜間模式

下圖是網易雲音樂的換膚功能

android換膚哪個簡單,Android一鍵換膚功能實作

經典

android換膚哪個簡單,Android一鍵換膚功能實作

換膚其實就是替換資源(文字、顔色、圖檔等)

一、換膚模式:

1.内置換膚

在Apk包中存在多種資源(圖檔、顔色值)用于換膚時候切換。

自由度低,apk檔案大  一般用于沒有其他需求的日間/夜間模式app

2.動态換膚

通過運作時動态加載皮膚包

android換膚哪個簡單,Android一鍵換膚功能實作

網易雲下載下傳的資源包

二、換膚流程

android換膚哪個簡單,Android一鍵換膚功能實作

流程

2.1 采集

android換膚哪個簡單,Android一鍵換膚功能實作

采集

2.2 如何采集

怎麼才能拿到所有的view這才是關鍵!那麼我們隻能從setContentView()入手

那麼問題來了setContentView()到底幹了什麼

檢視源碼發現setContentView()通過LayoutInflater将xml轉換成View加載到window中

android換膚哪個簡單,Android一鍵換膚功能實作

源碼三連

inflate幹了什麼?

android換膚哪個簡單,Android一鍵換膚功能實作

幹貨來了!!!!

LayoutInflate 的核心是createViewFromTag()

View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,

boolean ignoreThemeAttr) {

...............

View view;

if (mFactory2 !=null) {//核心View的建立工廠 是一個接口

view =mFactory2.onCreateView(parent, name, context, attrs);

}else if (mFactory !=null) {

view =mFactory.onCreateView(name, context, attrs);

}else {

view =null;

}

if (view ==null &&mPrivateFactory !=null) {

view =mPrivateFactory.onCreateView(parent, name, context, attrs);

}

if (view ==null) {

final Object lastContext =mConstructorArgs[0];

mConstructorArgs[0] = context;

try {

if (-1 == name.indexOf('.')) {//判斷是否是自定義View

view = onCreateView(parent, name, attrs);

}else {

view = createView(name,null, attrs);

}

}finally {

mConstructorArgs[0] = lastContext;

}

}

return view;

}

通過分析上面代碼可以看出Factory2如果不為空那麼就調用Factory2的方法建立View

否者就使用onCreateView()方法建立View

android換膚哪個簡單,Android一鍵換膚功能實作

那麼如果我們給定一個Factory那麼我們就可以監視所有的view

View設定資源檔案的流程如圖所示

android換膚哪個簡單,Android一鍵換膚功能實作

當我們拿到目前View的資源名稱時就會先去插件中的資源檔案裡找。

這就是換膚的原理

android換膚哪個簡單,Android一鍵換膚功能實作

加載外部Apk資源檔案

拿到資源檔案相信剩下的大家就知道怎麼玩了

代碼已經上傳給 github,歡迎大家一起讨論研究

使用方式

android換膚哪個簡單,Android一鍵換膚功能實作

初始化

android換膚哪個簡單,Android一鍵換膚功能實作

使用

皮膚包就是一個隻有資源檔案的Apk

大家可以看一下我其他文章哦