Android換膚

??目前比較流行的幾種換膚方案是基于開源框架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 基礎控件支持  
   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();
    }
皮膚開關

??如果項目中有特殊需求。例如, 股票控件: 控件顏色始終為紅色或綠色, 不需要隨著模式切換而換膚那么可以使用類似的方法, 直接設置drawable

setBackgroundDrawable(redDrawable)和background="#ce3d3a" // 不支持換膚 
setBackgroundResource(resId) 和background="@drawable/red"http://支持換膚
應用內換膚

??比如我想改變字體顏色,此時在colors里面添加

    <color name="background">#ff0000</color>//默認紅色
    <color name="background_night">#ff0</color>//變為黃色

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"/>

需要變色的地方調用

 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創建一個新的工程取名為skin-night,將新的工程下的mipmap,values下的style以及build.gradle下的dependencies節點刪除(刪除后生成的皮膚包會比較精致,皮膚包大小會很小)
??比如我們需要替換ImageView的背景以及TextView的顏色。
假如原APK的drawable下有一張test.png的圖片,我們在skin-night的drawable下也要有一張test.png的圖片
??原APK的TextView顏色
colors.xml

    <color name="background">#ff0000</color>//默認紅色

??skin-night工程中設置
colors.xml

 <color name="background">#ff0</color>//變為黃色

Build->Build APK->將生成的.apk改成night.skin,并將其復制到assets下的skins目錄下

skin.png

需要變色的地方調用

 //原理為先將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卡下加載皮膚包

??皮膚包可以放在服務器上,從而減小了APK的負擔。從服務器中下載到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卡根目錄


111111111.png

需要變色的地方調用以下代碼即可

  SkinCompatManager.getInstance().loadSkin("night.skin", null, CustomSDCardLoader.SKIN_LOADER_STRATEGY_SDCARD);
動態添加的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本身的顏色(需要改變畫筆顏色),我的思路是當需要改變皮膚時,我們回調自定義View中的方法,在此方法中改變畫筆的顏色,然后 invalidate();重繪一次。

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

推薦閱讀更多精彩內容