??目前比較流行的幾種換膚方案是基于開源框架Android-skin-support、Android-Skin-Loader蛇摸、修改樣式換膚還有鴻洋的換膚方案。本文介紹的是基于Android-skin-support的換膚方案https://github.com/ximsfei/Android-skin-support
1.依賴
compile'skin.support:skin-support:2.2.3' // skin-support 基礎(chǔ)控件支持
compile 'skin.support:skin-support-design:2.2.3' // skin-support-design material design 控件支持[可選] 其他的可參考官方文檔疯暑。
2.使用
在MyApplication的onCreate中初始化
SkinCompatManager.withoutActivity(this)
.addInflater(new SkinMaterialViewInflater())
//如果需要從sd卡的指定目錄中加載皮膚
.addStrategy(new CustomSDCardLoader())
.loadSkin();
}
皮膚開關(guān)
??如果項目中有特殊需求顿颅。例如, 股票控件: 控件顏色始終為紅色或綠色, 不需要隨著模式切換而換膚那么可以使用類似的方法, 直接設(shè)置drawable
setBackgroundDrawable(redDrawable)和background="#ce3d3a" // 不支持換膚
setBackgroundResource(resId) 和background="@drawable/red"http://支持換膚
應(yīng)用內(nèi)換膚
??比如我想改變字體顏色恍涂,此時在colors里面添加
<color name="background">#ff0000</color>//默認(rèn)紅色
<color name="background_night">#ff0</color>//變?yōu)辄S色
layout中
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好"
android:textColor="@color/background"
android:textSize="@dimen/dm_50sp"/>
需要變色的地方調(diào)用
SkinCompatManager.getInstance().loadSkin("night",SkinCompatManager.SKIN_LOADER_STRATEGY_BUILD_IN);//night表示colors中background_night的后綴
還原為原來的皮膚
SkinCompatManager.getInstance().loadSkin("night.skin", null, CustomSDCardLoader.SKIN_LOADER_STRATEGY_SDCARD);
插件式換膚(制作皮膚包)
Assesets下加載皮膚包
??File->New->New Module創(chuàng)建一個新的工程取名為skin-night宝惰,將新的工程下的mipmap,values下的style以及build.gradle下的dependencies節(jié)點刪除(刪除后生成的皮膚包會比較精致再沧,皮膚包大小會很心岫帷)
??比如我們需要替換ImageView的背景以及TextView的顏色。
假如原APK的drawable下有一張test.png的圖片炒瘸,我們在skin-night的drawable下也要有一張test.png的圖片
??原APK的TextView顏色
colors.xml
<color name="background">#ff0000</color>//默認(rèn)紅色
??skin-night工程中設(shè)置
colors.xml
<color name="background">#ff0</color>//變?yōu)辄S色
Build->Build APK->將生成的.apk改成night.skin淤堵,并將其復(fù)制到assets下的skins目錄下
需要變色的地方調(diào)用
//原理為先將assets下將皮膚包拷貝到緩存,再從緩存中加載皮膚包
SkinCompatManager.getInstance().loadSkin("night.skin",SkinCompatManager.SKIN_LOADER_STRATEGY_ASSETS);//night.skin為皮膚包的名稱
還原為原來的皮膚
SkinCompatManager.getInstance().loadSkin("night.skin", null, CustomSDCardLoader.SKIN_LOADER_STRATEGY_SDCARD);
SD卡下加載皮膚包
??皮膚包可以放在服務(wù)器上顷扩,從而減小了APK的負(fù)擔(dān)拐邪。從服務(wù)器中下載到SD卡,然后加載SD卡上的皮膚包隘截。
在MyApplication的onCreate中初始化中添加addStrategy(new CustomSDCardLoader())
SkinCompatManager.withoutActivity(this)
.addInflater(new SkinMaterialViewInflater())
//如果需要從sd卡的指定目錄中加載皮膚
.addStrategy(new CustomSDCardLoader())
.loadSkin();
}
CustomSDCardLoader繼承自SkinSDCardLoader
public class CustomSDCardLoader extends SkinSDCardLoader {
public static final int SKIN_LOADER_STRATEGY_SDCARD = Integer.MAX_VALUE;
@Override
public String loadSkinInBackground(Context context, String skinName) {
return super.loadSkinInBackground(context, skinName);
}
//自定義加載皮膚包的路徑(我們的皮膚包必須要放在getSkinPath返回的路徑下扎阶。否則加載失斝谖浮)
@Override
protected String getSkinPath(Context context, String skinName) {
return new File("sdcard"+File.separator+skinName).getAbsolutePath();
}
@Override
public int getType() {
return SKIN_LOADER_STRATEGY_SDCARD;
}
}
將night.skin push到SD卡根目錄
需要變色的地方調(diào)用以下代碼即可
SkinCompatManager.getInstance().loadSkin("night.skin", null, CustomSDCardLoader.SKIN_LOADER_STRATEGY_SDCARD);
動態(tài)添加的View
我們只需要將添加的View寫在布局中,然后添加此布局即可
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
TextView textview = (TextView)View.inflate(this, R.layout.textview, null);
params.gravity = Gravity.CENTER;
mLinearLayout.addView(textview, params);
textview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好"
android:textColor="@color/background">
</Text
自定義View
??官方demo給我們的自定義TextView只是改變背景和文字顏色东臀,可能我們需要的更多是改變自定義View本身的顏色(需要改變畫筆顏色)着饥,我的思路是當(dāng)需要改變皮膚時,我們回調(diào)自定義View中的方法啡邑,在此方法中改變畫筆的顏色贱勃,然后 invalidate();重繪一次。