Skip to content

Latest commit

 

History

History
252 lines (175 loc) · 6.02 KB

README.md

File metadata and controls

252 lines (175 loc) · 6.02 KB

Android 动态换肤框架

Android 动态换肤框架,支持动态加载插件资源,无需重启Activity,拓展能力很强



演示

Pixel 4 XL Android 13 实机测试

95b973c2ead665e65a1e17461d55e276.mp4

下载演示Demo






使用

1、实现换肤能力

将需要换肤页面的Activity继承自SkinBaseActivity

public class MainActivity extends SkinBaseActivity {
    //....
}




2、加载皮肤包

  SkinManager.INSTANCE.loadSkinFile(Environment.getExternalStorageDirectory() + "/skin.apk");


对于Assets目录,使用

SkinManager.INSTANCE.loadSkinAssets("skin.apk");

加载Assts文件,会copy一份到sdcard下,具体路径为:  /sdcard/Android/data/${packageName}/cache/skinCache/**.apk
更推荐使用SkinManager.INSTANCE.loadSkinFile



使用app:skinEnable="true or false" 来决定View是否开启换肤。
优先级大于setSkinGlobalEnable,默认全局开启







换肤能力

框架默认支持backgroundsrctextColortext常用资源切换,若需要增加功能


使用addSkinAttrHolder方法添加需要的属性

public <T> void addSkinAttrHolder(String attrName, ISkinMethodHolder<? extends View, ?> methodHolder)


这个方法接收两个参数

  1. 第一个参数是属性名,如:
<EditText
  android:id="@+id/editText"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:textColorHint="@color/color_blue_50" />

这里有一个EditText,我们要增加textColorHint的换肤能力,那么属性名就是textColorHint.



  1. 第二个参数是属性set方法的方法引用,如 EditText::setHintTextColor
示例
ISkinMethodHolder<EditText, Integer> setHintTextColor = EditText::setHintTextColor;
SkinManager.INSTANCE.addSkinAttrHolder("textColorHint", setHintTextColor);

到这里,我们增加一个换肤能力就实现了!!!




请注意,ISkinMethodHolder<EditText, Integer>接口中的第二个类型表示的是set方法的参数类型

必须是设置资源值的方法,不能使用设置资源Id的重载方法!!!

原因是我们即使我们传入资源包中的资源ID,set方法内部也是通过APP的Resource对象获取的





关于复杂参数的set方法处理

比如TextViewsetTextSize()方法,接受两个参数: image.png


我们还是可以通过方法引用来实现,这里需要转化一下

处理方式

static void setTextSize(TextView view, float px) {
    view.setTextSize(TypedValue.COMPLEX_UNIT_PX, px);
}

public static final ISkinMethodHolder<TextView, Float> setTextSize = SkinMethod::setTextSize;


//	......

SkinManager.INSTANCE.addSkinAttrHolder("textSize", setTextSize);



关于自定义View,请提供属性的set方法即可








功能拓展

MethodAcceptAndThen

使用ISkinMethodHolder.andThen()来转换成MethodAcceptAndThen对象 这是对ISkinMethodHolder的功能拓展,增加了一个after操作,用于这条属性在执行完换肤之后的操作.


注意!! 只有设置了 app:skinMethodTag=""属性的View 才会执行此操作,未设置完全不会执行

<TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="默认主题"
  app:skinMethodTag="title"
  android:textColor="@color/color_blue_50" />
示例
//文字颜色
ISkinMethodHolder<TextView, Integer> setTextColor = TextView::setTextColor;
MethodAcceptAndThen<TextView, Integer> setTextColorAndThen = setTextColor.andThen((textView, integer) -> {
    if ("title".equals(textView.getTag(R.id.skinMethodTagID))) {
        textView.setText("春节主题皮肤");
    }
});
SkinManager.INSTANCE.addSkinAttrHolder("setTextColor", setTextColorAndThen);



MethodAcceptProxy

使用ISkinMethodHolder.proxy()来转换成MethodAcceptProxy对象 这是对ISkinMethodHolder的功能拓展,代理当前set方法,实现自己逻辑.


示例
ISkinMethodHolder<View, Drawable> setBackground = View::setBackground;
MethodAcceptProxy<View, Drawable> setBackgroundProxy = setBackground.proxy((view, value, methodHolder) -> {
    if ("mProxyTag".equals(textView.getTag(R.id.skinMethodTagID))) {
        //You can do something
    }
});
SkinManager.INSTANCE.addSkinAttrHolder("setBackground", setBackgroundProxy);

注意!! 只有设置了app:skinMethodTag=""属性的View才会执行此操作,未设置完全不会执行






API参考

loadDefault() 重置换肤,切换为默认
getSkinResource() 获取资源包的资源对象,如果为空,返回APP的资源对象
isSkinState() 是否为换肤状态
isSkinGlobalEnable() 是否已启用全局换肤
setSkinGlobalEnable(boolean enable) 设置是否启用全局换肤开关,默认为true,可通过{app:skinEnable="boolean"}属性单独给View设置
getColor() 根据资源ID获取资源包中的Color颜色值
getDrawable() 根据资源ID获取资源包中的drawable对象
getString() 根据资源ID获取资源包中的字符
getDimension() 根据资源ID获取资源包中的Dimension资源值
getSkinResId(@IdRes int resId) 根据资源Id获取到皮肤包中的Id.