CoderAlee / PaintedSkin

一款解决Android App 换肤框架,极低的侵入性与学习成本。
Apache License 2.0
166 stars 23 forks source link

怎么设置多个皮肤包 #26

Closed ylmyg closed 2 years ago

ylmyg commented 2 years ago

我想问下多个皮肤包如何写呢?我这样写还是只能设置一种皮肤包 internal class OptionFactory : IOptionFactory { override fun defaultTheme(): Int { return 0 }

override fun requireOption(theme: Int): IThemeSkinOption? {
    return when (theme) {
        1 -> NightOption()//一种皮肤包
        2 -> Night2Option()//另一种皮肤包
        else -> null
    }
}

} ThemeSkinService.getInstance().switchThemeSkin(1)//调用第一种 ThemeSkinService.getInstance().switchThemeSkin(2)//调用第二种

ylmyg commented 2 years ago

就是说每设置一种皮肤包就需要实例化一个NightOption()是么?

CoderAlee commented 2 years ago

IThemeSkinOption 是每个皮肤包的配置项

CoderAlee commented 2 years ago

如果你有多套皮肤要进行切换,那么应当每套皮肤都有对应的IThemeSkinOption实现类。 而如果你有两套皮肤,第一套黑夜、第二套黑夜皮肤的新年版本。其中新年版本只希望替换部分颜色或drawable。那么在一个ThemeSkinOption中即可实现

ylmyg commented 2 years ago

感谢回复,还想请教一下
1 第一套黑夜、第二套黑夜皮肤的新年版本 只需要设置一个ThemeSkinOption,我想的是黑夜和新年版本不是分别不通的皮肤么?只能在相同的ThemeSkinOption做区分呢?通过skin:enable="true"做区分么? 2 我项目中有imgView是通过setColorFilter设置颜色的,换肤以后设置不成功,请问该如何做?

ylmyg commented 2 years ago

可以了,通过设置ThemeSkinService.getInstance().currentThemeSkinPack.getColor(R.color.white) 1 xxx.setxxx(ThemeSkinService.getInstance().currentThemeSkinPack.getColor(R.color.white)) 2 WindowManager.getInstance().getWindowProxy(this).addEnabledThemeSkinView(xxx, SkinElement("textColor", R.color.color_black)) 我不明白这两种方法有什么本质的区别? 第一种是自定义背景颜色或者颜色 第二种也是可以改变颜色的

CoderAlee commented 2 years ago

可以了,通过设置ThemeSkinService.getInstance().currentThemeSkinPack.getColor(R.color.white) 1 xxx.setxxx(ThemeSkinService.getInstance().currentThemeSkinPack.getColor(R.color.white)) 2 WindowManager.getInstance().getWindowProxy(this).addEnabledThemeSkinView(xxx, SkinElement("textColor", R.color.color_black)) 我不明白这两种方法有什么本质的区别? 第一种是自定义背景颜色或者颜色 第二种也是可以改变颜色的

ThemeSkinService.getInstance().currentThemeSkinPack.getxxx 是主动从当前皮肤包内获取资源。如果发生主题切换,需要注册ISwitchThemeSkinObserver ,在接收到onThemeSkinSwitchRunOnUiThread 后再次为view设置资源。 而addEnabledThemeSkinView 会将View需要换肤的属性交给换肤框架维护,在每次发生主题切换时。框架内自动为view替换最新皮肤包提供的资源

CoderAlee commented 2 years ago

感谢回复,还想请教一下 1 第一套黑夜、第二套黑夜皮肤的新年版本 只需要设置一个ThemeSkinOption,我想的是黑夜和新年版本不是分别不通的皮肤么?只能在相同的ThemeSkinOption做区分呢?通过skin:enable="true"做区分么? 2 我项目中有imgView是通过setColorFilter设置颜色的,换肤以后设置不成功,请问该如何做?

  1. 如果黑夜新年皮肤只需要替换返回按钮、logo等,对黑夜皮肤包内一小部分元素进行替换。那么此时黑夜新年皮肤包可以不包含所有元素,只提供需要将黑夜皮肤包内的元素进行替换的元素。我的描述可能不是很好理解,这个功能计划会出一个demo来帮助理解
  2. skin:enable="true" 是用来在XML中标识哪些View支持换肤的。
CoderAlee commented 2 years ago

可以了,通过设置ThemeSkinService.getInstance().currentThemeSkinPack.getColor(R.color.white) 1 xxx.setxxx(ThemeSkinService.getInstance().currentThemeSkinPack.getColor(R.color.white)) 2 WindowManager.getInstance().getWindowProxy(this).addEnabledThemeSkinView(xxx, SkinElement("textColor", R.color.color_black)) 我不明白这两种方法有什么本质的区别? 第一种是自定义背景颜色或者颜色 第二种也是可以改变颜色的

ThemeSkinService.getInstance().currentThemeSkinPack.getxxx 是主动从当前皮肤包内获取资源。如果发生主题切换,需要注册ISwitchThemeSkinObserver ,在接收到onThemeSkinSwitchRunOnUiThread 后再次为view设置资源。 而addEnabledThemeSkinView 会将View需要换肤的属性交给换肤框架维护,在每次发生主题切换时。框架内自动为view替换最新皮肤包提供的资源

addEnabledThemeSkinView 提供的初衷是为了帮助使用者解决在代码中创建的View无法通过框架自动换肤的,以及一些view需要根据业务逻辑来决定使用的资源(比如一个TextView 要根据用户输入的内容显示不同的颜色,且字体颜色还要支持不同主题)。同时作为一个开发者,我认为一个好的框架应当尽量少的侵入到接入者的代码中。这样既可以减轻接入难度、降低三方库替换难度也使接入者的代码更专注于原有业务。

ylmyg commented 2 years ago

我可以这样理解么? ThemeSkinService.getInstance().currentThemeSkinPack.getxxx 是我主动按照皮肤切换的生命周期自己替换皮肤 addEnabledThemeSkinView 是由框架帮我替换皮肤

CoderAlee commented 2 years ago

我可以这样理解么? ThemeSkinService.getInstance().currentThemeSkinPack.getxxx 是我主动按照皮肤切换的生命周期自己替换皮肤 addEnabledThemeSkinView 是由框架帮我替换皮肤

没有问题