ScoopsDemo
基本用法
- 简要说明
Scoops是一个android应用库,主要解决的是多主题实现方案。通过配置多个R.style.Theme ,代码进行动态设置主题,重启当前界面实现。
- 原理分析
主要通过设置主题(存储设置值), 重启activity,通过setTheme方式设置style实现。
- 使用方法
1项目的build.gradle里面

2 模块的build.gradle里面


3 values里面加入themes.xml
配置一些主题,为了多主题更换使用
4 AndroidManifest.xml里面
配置上默认主题,这里要注意的是配置的和5里面写的默认的那个要一致

5 MainApp里面
完成初始化,主要设置一系列的主题。其中addToppings为的是注释的时候使用,后面会讲它的用法。setSharedPreferences 配置默认的存储key值addDayNightFlavor 设置DayNight的主题风格,这个随后会讲到。

6 在MainAcitvity里面
1:需要继承AppCompatActivity
2:需要在setContentView前面调用Scoop.getInstance().apply(this);将主题设置进来。

3:这里说下为什么需要在AndroidManifest.xml里面配置默认主题,因为Scoops设计,在判断主题没有更改的情况下,不进行设置主题,因此第一次进来不会设置。所以我们要配置默认主题。并且和MainApp里面设置的默认值一样。

这里的true第三个参数说明设置为默认主题,和我们在AndroidManifest.xml设置的主题一致即可。
7 效果如下

8 代码地址
官网 地址 https://github.com/52inc/Scoops
demo地址 https://github.com/luxiaoming/ScoopsDemo
注解用法
- 简要说明
通过注释方式,完成多主题的效果更换。可以减少一些代码,使得代码更清晰一些。
- 使用说明
1 首先写一个注释类

2 在MainApp
初始化的时候,将注释通过addToppings方式设置进去

3 在MainActivity
使用注释@BindToppingStatus 标记下状态栏的颜色跟随
使用注释@BindTopping 标记下某个控件的颜色跟随
@BindTopping标记里面还可以有参数
1 value对应Toppings里面的某个值
2 adapter 跟上一个适配器,主要是为了实现某些控件自定义的设置颜色方案
3 interpolator 可以配置颜色切换过程效果,比如AccelerateInterpolator.class

4使用

5 ColorAdapter适配器
如果需要自己自定义主题更换后的view颜色变换动作(主要是有时候不符合我们的需求,比如我们想动态改文本颜色,高亮色等),我们就需要自定义一个实现ColorAdapter的类,比如ButtonColorAdapter接口 ColorAdapter定义了两个方法
设置新的颜色值
void applyColor(T view, @ColorInt int color);
获取当前颜色值
int getColor(T view);

6 主题bug
1 使用 @BindTopping 注释的时候,必须加上adapter=XXX.class 如果用默认的 ,请加上adapter = DefaultColorAdapter.class
2 默认的设置ScoopSettingsActivity界面,当设置为默认主题的时候,会出现bug。原因是这个界面指定了主题android:theme=”@style/Theme.AppCompat.Light” 如果我们默认的界面指定的跟这个不一样,则这个设置界面则会在默认主题的时候出错,和设置的效果不一致。解决方案:自己写一个设置界面呗。
7 demo地址
https://github.com/luxiaoming/ScoopsDemo
Butter Knife 注释编程阅读地址:
http://mp.weixin..com/s?__biz=MzI1MjMyOTU2Ng==&mid=&idx=1&sn=9fc37fdb8fb2696c03070db0&scene=4#wechat_redirect
白天夜间主题
很多应用都有这个功能,可以选择白天和夜间模式,给用户更好的体验。为此,系统也提供了一种机制,来实现此功能。
模式主要分为四种 夜间 白天 跟随系统 和自动。具体实现可以去看com.android.support:appcompat-v7:23.0.0源码

不使用Scoops方式
1自定义一个属性Attrs.xml

这里可以看到定义了两个属性textColor和textSize 格式分别为color和dimension
2创建一个目录values-night
3在values和values-night下面
新建一个文件themes.xml,同时配置相同的主题,加入我们自定义的属性textColor,给它配置值。
values下的属性

values-night下的属性

4使用的地方

这里mMode的值可以取以下几个
MODE_NIGHT_FOLLOW_SYSTEM
MODE_NIGHT_YES
MODE_NIGHT_NO
MODE_NIGHT_AUTO
5我们配置下使用的地方

这里的 android:textColor=”?attr/textColor” 记住用的是?attr来使用自定义的属性
6具体的结果,看Primary Color颜色变化

7代码地址
https://github.com/luxiaoming/ScoopsDemo
使用Scoops方式
1:MainApp

使用addDayNightFlavor将一个主题设置为DayNight模式
2:在对应的主题里面配置上文本颜色
values里面

values-night里面

3:进入app,在设置里面设置成dayNight模式后,点击按钮Scoops方式查看效果即可。
4:效果如下

5:代码地址
https://github.com/luxiaoming/ScoopsDemo
原理分析
核心代码位置
https://github.com/52inc/Scoops/tree/master/scoops/src/main/java/com/ftinc/scoop可以看到主要文件

Flavor.java 存储每个主题信息
Scoop.java 主文件,主要提供接口,作为对外调用。
SugarCone.java 解析注释的主文件,通过使用bind方法,去反射找到编译出来的Toppings类,通过这个来关联上来。
Topping.java 自定义注释方法。标记在属性上面,然后通过编译时候,使用插件scoops-compiler,生成后缀为Toppings的绑定类,随后我们使用bind函数,将这些类和界面关联起来。
关键方法
Scoop.apply函数

我们来看下public void apply(Activity activity)的具体代码流程找到当前的主题getCurrentFlavor

判断主题是否是白天夜间模式,如果是,设置模式然后使用

另一个apply方法,参数是activity和主题id设置主题,找到设置的背景色,设置窗体背景,然后返回去,我们自己recreate 重新启动当前界面,实现切换。
编译插件
https://github.com/52inc/Scoops/tree/master/scoops-compiler
主要目的是解析我们自定义的注解。解析的主要是我们在初始化时候使用addToppings加入的我们的注解。找到后,解析出来注解的标记值,切换过场特效,和适配器。标记值的目的是更新值的时候,用这个来做区分。

代码逻辑:找到所有的绑定在这个标记的view,然后逐个调用对应的适配器,进行对应的颜色更新。我们来看下核心的bind函数

我们看下bind 代码,主要看下getViewBinder这个方法即可。继续去看findViewBinderForClass 函数

代码主要流程为:从缓存能找到,直接返回。找不到,然后查找Class.forName(clsName + “_ToppingBinder”)类,构造一个,然后将这个返回,并缓存下来。然后调用里面的bind进行关联view我们反编译可以看到MainActivity_ToppingBinder.smali这个smali文件,这个就是插件生成出来的代码。我们反编译下,看下这个文件做了什么。

看到了吧,将注释的全部归类进来,为后面更新的时候查找使用。注释的原理就是如此了。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/123061.html