Android 一键换肤框架 Android-skin-support 使用教程

3,906 阅读5分钟

前言

节后由于一些原因一直没有更新新的内容,都说新年新气象,今天简单介绍一款能够让Android项目轻松实现换肤的开源框架Android-skin-support。

之所以选择介绍这一款框架是因为它使用起来真的非常方便,它不仅仅支持应用内换肤,还支持插件式换肤。

应用内换肤

就是将白天和夜间两套资源文件根据一定的命名规则放在同一个项目资源文件夹中即可实现换肤。

插件式换肤

使用自制的皮肤包完成换肤功能,这个皮肤包可以打包进项目也可以存放在设备指定路径上。

好了,废话不多说,这就简单介绍一下如何快速正确集成框架吧~

框架导入

1、support library

implementation 'skin.support:skin-support:3.1.4'                   // skin-support 基础控件支持
implementation 'skin.support:skin-support-design:3.1.4'            // skin-support-design material design 控件支持[可选]
implementation 'skin.support:skin-support-cardview:3.1.4'          // skin-support-cardview CardView 控件支持[可选]
implementation 'skin.support:skin-support-constraint-layout:3.1.4' // skin-support-constraint-layout ConstraintLayout 控件支持[可选]

2、AndroidX

implementation 'skin.support:skin-support:4.0.5'                   // skin-support
implementation 'skin.support:skin-support-appcompat:4.0.5'         // skin-support 基础控件支持
implementation 'skin.support:skin-support-design:4.0.5'            // skin-support-design material design 控件支持[可选]
implementation 'skin.support:skin-support-cardview:4.0.5'          // skin-support-cardview CardView 控件支持[可选]
implementation 'skin.support:skin-support-constraint-layout:4.0.5' // skin-support-constraint-layout ConstraintLayout 控件支持[可选]

初始化

框架初始化需要在应用Application的oncreate中进行初始化。

1、support library

SkinCompatManager.withoutActivity(this)                         // 基础控件换肤初始化
            .addInflater(new SkinMaterialViewInflater())            // material design 控件换肤初始化[可选]
            .addInflater(new SkinConstraintViewInflater())          // ConstraintLayout 控件换肤初始化[可选]
            .addInflater(new SkinCardViewInflater())                // CardView v7 控件换肤初始化[可选]
            .setSkinStatusBarColorEnable(false)                     // 关闭状态栏换肤,默认打开[可选]
            .setSkinWindowBackgroundEnable(false)                   // 关闭windowBackground换肤,默认打开[可选]
            .loadSkin();

2、AndroidX

SkinCompatManager.withoutActivity(this)
            .addInflater(new SkinAppCompatViewInflater())           // 基础控件换肤初始化
            .addInflater(new SkinMaterialViewInflater())            // material design 控件换肤初始化[可选]
            .addInflater(new SkinConstraintViewInflater())          // ConstraintLayout 控件换肤初始化[可选]
            .addInflater(new SkinCardViewInflater())                // CardView v7 控件换肤初始化[可选]
            .setSkinStatusBarColorEnable(false)                     // 关闭状态栏换肤,默认打开[可选]
            .setSkinWindowBackgroundEnable(false)                   // 关闭windowBackground换肤,默认打开[可选]
            .loadSkin();

注意:如果项目中使用的Activity继承自AppCompatActivity,需要重载getDelegate()方法

@NonNull
@Override
public AppCompatDelegate getDelegate() {
    return SkinAppCompatDelegateImpl.get(this, this);
}

换肤

换肤支持两种方式,这里简单的介绍这两种方式分别如何实现:

应用内换肤

第一步:指定资源目录

使用应用内换肤需要在项目中指定目标皮肤所在资源文件夹,因此需要在对应module的build.gradle文件中配置一下这个资源目录信息,配置方式如下:

sourceSets {
    main {
        res.srcDirs = ['src/main/res',
                       'src/main/res-night']
    }
}

第二步:配置指定后缀的资源文件 应用内换肤只需要你将不同主题的两张图片或者颜色等资源文件以添加前缀或者后缀的方式进行命名存放在项目资源文件夹当中即可,例如:

R.color.windowBackgroundColor 对应 R.color.windowBackgroundColor_night

R.mipmap.home 对应 R.mipmap.home_night

第三步:切换主题

在需要切换现实主题的时候使用如下方法切换即可:

SkinCompatManager.getInstance().loadSkin("night", SkinCompatManager.SKIN_LOADER_STRATEGY_BUILD_IN); // 后缀加载
SkinCompatManager.getInstance().loadSkin("night", SkinCompatManager.SKIN_LOADER_STRATEGY_PREFIX_BUILD_IN); // 前缀加载

插件式换肤

插件式换肤主要是使用皮肤包进行资源替换,所以这里就涉及到如何制作皮肤以及加载皮肤了。

第一步:制作皮肤包

  • 创建新的不同包名的项目
  • 将同名不同皮肤的资源文件存放在对应的资源文件夹中
  • 打包成apk文件后改成后缀名为.skin的文件

第二步:使用皮肤包

使用皮肤包常用的有两种方式:

  • 项目assets/skins文件夹存放

    使用这种方式切换皮肤时需要使用下面的方式进行切换。

    SkinCompatManager.getInstance().loadSkin("night.skin", SkinCompatManager.SKIN_LOADER_STRATEGY_ASSETS);
    
  • 设备sdcard存放

    存放在sdcard的皮肤包在使用时稍微有一点麻烦,需要先进行加载器的自定义,主要目的是指定皮肤包路径,然后在进行切换。

    1、自定义加载器

    继承自SkinSDCardLoader,通过getSkinPath方法指定皮肤加载路径,通过getType方法指定加载器type。

    public class CustomSDCardLoader extends SkinSDCardLoader {
        public static final int SKIN_LOADER_STRATEGY_SDCARD = Integer.MAX_VALUE;
    ​
        @Override
        protected String getSkinPath(Context context, String skinName) {
            return new File(SkinFileUtils.getSkinDir(context), skinName).getAbsolutePath();
        }
    ​
        @Override
        public int getType() {
            return SKIN_LOADER_STRATEGY_SDCARD;
        }
    }
    

    加载器定义完成后需要在Application中进行初始化。

    SkinCompatManager.withoutActivity(this)
            .addStrategy(new CustomSDCardLoader());          // 自定义加载策略,指定SDCard路径
    

    2、切换皮肤

    SkinCompatManager.getInstance().loadSkin("night.skin", null, CustomSDCardLoader.SKIN_LOADER_STRATEGY_SDCARD);
    

特殊情况处理

1、指定控件不进行换肤

如果你需要某一个控件不进行换肤,只需要直接使用drawable对资源进行设置即可,如:

setBackgroundDrawable(redDrawable) // 不支持换肤
background="#ce3d3a"

而不是使用R.drawable.red
setBackgroundResource(R.drawable.red)
background="@drawable/red"

2、动态添加皮肤颜色

SkinCompatUserThemeManager.get().addColorState(R.color.colorPrimary, #ffffffff);

SkinCompatUserThemeManager.get().addColorState(R.color.colorPrimary, new ColorState.ColorBuilder().addXxx().build());

// 清除所有已有颜色值。
SkinCompatUserThemeManager.get().clearColors();

// 设置完成后使用apply保存
SkinCompatUserThemeManager.get().apply();

3、动态设置皮肤图片

SkinCompatUserThemeManager.get().addDrawablePath(R.drawable.windowBackground, "/sdcard/DCIM/Camera/xxx.jpg");

// 要换肤的资源id,图片路径,图片旋转角度(默认为0)
SkinCompatUserThemeManager.get().addDrawablePath(R.drawable.windowBackground, "/sdcard/DCIM/Camera/xxx.jpg", 90);

// 清除所有已有图片路径。
SkinCompatUserThemeManager.get().clearDrawables();

// 设置完成后使用apply保存
SkinCompatUserThemeManager.get().apply();

写在最后

关于Android-skin-support换肤框架的介绍就告一段落了,关于如何自定义皮肤控件可以参考项目文档。由于框架使用较为简单,就不在提供相关demo了,项目中也有demo可以查看。

最后的最后,如果有任何问题也欢迎评论、私信交流,喜欢我的分享也可以关注我哟~