原标题:Prism(棱镜)——一款优秀的Android 主题动态切换框架

相关阅读:

Prism(棱镜) 是一个全新的 Android 动态主题切换框架,虽然是头一次发布,但它所具备的基础功能已经足够强大了!本文介绍了 Prism 的各种用法,希望对你会有所帮助,你也可以对它进行扩展,来满足开发需求。

先说一下 Prism 的诞生背景。其实我没打算一上来就写个框架出来,当时在给写一些使用 ViewPager 来实现 UI 动态着色的系列文章,文中用到的代码被我重构成适合讲解用的组件,然后我发现这些代码可以整理成一个简洁的 API,于是乎便有了做 Prism 框架的想法。我把 Prism 拿给我比较认可的几个人看,他们都觉得不错,这样我就一点点把它做成了库。经过反复使用,我觉得这个 API 在保持架构简洁的同时已经具备了很多的功能,就决定把它发布出来了跟大家分享。

Prism 分为三个独立库:

prism是 Prism 的核心库

prism-viewpager实现了 ViewPager 与核心库的对接

prism-palette实现了 Palette 调色板与核心库的对接

目前已发布的版本是,最新版本的链接是。

添加好必要的依赖就可以使用 Prism 了。

Prism 基本上由三种对象类型构成:Setter、Filter和 Trigger。

Setter用来设置 UI 对象的颜色,一般是 View 但也可以是其他元素,后面会讲到。它的基本用法是将 setColour(int colour)(或 setColor(int color))映射到 View 封装的某个方法上。例如,内置的 ViewBackgroundSetter 会映射到 setBackgroundCOLOR(int color) 上。有时 Setter 在不同版本的 Android 上会产生不同的效果,例如 StatusBarSetter 在 Android Lollipop (5.0) 之前的系统上不起作用,因为 Lollipop 之前的版本不支持改变 StatusBar 的颜色。不过 Prism 会随机应变,不会引起程序崩溃,请放心使用,一切交由 Setter 搞定。

Prism 内置有如下几个基本的 Setter:

FabSetter(FloatingActionButton fab)

为中的 FloatingActionButton(简写 FAB)设置背景色。

StatusBarSetter(Window window)

设置指定窗体的状态栏颜色,注意它的操作对象并不是 View。

TextSetter(TextView textView)

设置 TextView 中的文本颜色。

ViewBackgroundSetter(View view)

设置 View 的背景颜色。

当然,你也可以创建新的 Setter 给自定义 View 中的不同组件设置颜色,或者给同一个 View 创建多个 Setter 来设置不同的属性,同时对不同组件进行着色。只要把自定义的 Setter 添加到 Prism 中即可生效。

Filter可以对颜色进行转化处理。一般向 Prism 传入的是一个颜色值,有时我们可能需要把该颜色的不同色度应用到不同的 UI 组件上,这时要用 Filter 将颜色进行一下转换再输出。内置的基本 Filter 有:

IdentifyFilter()

返回与输入相同的颜色。

ShadeFilter(float amount)

将输入颜色与黑色混合进行加深处理。amount 为 0 到 1 之间的浮点数,代表黑色的混合比率。当 amount 为 0 时,输出颜色就是输入颜色;为 1 时,则输出纯黑色。

TintFilter(float amount)

将输入颜色与白色混合进行加亮处理。amount 为 0 到 1 之间的浮点数,代表白色的混合比率。当 amount 为 0 时,输出颜色就是输入颜色;为 1 时,则输出纯白色。

Trigger是颜色变化时所触发的事件。通常它会调用 Prism 实例上的setColour(int colour),将颜色变化的消息传递给在该实例上注册过的所有 Setter 方法。

因为 Trigger 需要额外的依赖库,所以 Prism 核心库没有将它包含进去,但在 ViewPager 和 Palette 的扩展库中都有提供。

上面的代码大部分都是基本的 Android 开发操作,不需要特别的解释。重点看一下创建 Prism 实例的部分——先创建一个将输入颜色加亮 50% 的 Filter(TintFilter),然后创建 Prism.Builder 实例,并添加 AppBar 实例(这会为 AppBar 创建一个 Setter 来设置背景色)、Window(为 StatusBarColour 创建 Setter 来设置状态栏颜色)、TextView(使用text(TextView)来设置文字颜色),以及 FloatingActionButton(设置 FAB 背景色并应用第一步中的 TintFilter)。最后用build()来完成 Prism 实例的构建。

现在所有组件都被串联了起来,此时只要调用该实例上的setColour(int colour)就可以同时改变这些组件的颜色:

prism.setColour(0xFF0000);

代码最后明确使用了 onDestroy() 来清除 Prism 实例。其实严格来说这一步并不是必须要有,因为等到 Activity 被清除后,系统不会保留对 Prism 实例的引用,垃圾回收器会将 Prism 实例处理掉。不过如果后面真不会再用的话,及时做下手工清理也无妨。

Prism 的基本用法就是这样,只要在 onCreate() 中增加六行代码,就能同时改变各组件的颜色(下面使用了 FloatingActionButton 来触发颜色切换)。

把 Setter 和 Filter 配合起来使用省去了大量的样板代码,让事情简单好多,实际上它们完成的工作并不复杂,但如果搭配 Trigger 使用,情况就不一样了。

首先将 prism-viewpager做为依赖添加到项目中来,对应的 build.gradle 内容如下:

Trigger 是 Prism 实例最前方的关卡,它来触发主题颜色的改变。我们先来看一下 ViewPagerTrigger 如何根据用户操作来触发 ViewPager 改变颜色。ViewPager 的 Adaptor 要为每个页面位置提供颜色信息,这需要通过 ColourProvider 接口来完成(或 ColorProvider,如果不介意使用这种拼写方式所带来的少许性能损失的话):

如果你用过 PagerTitleStrip 或 Design Library 中的 TabLayout,那对给每个页面位置提供一个标题的做法就不陌生了。ColourProvider 接口就是这个作用,只不过它把标题的字符串换成了 RGB 颜色值。Adapter 已内置了getCount()方法,所以在继承 Adapter 时不用重新定义这个方法,可以按下面的示例来实现自己的 Adaptor:

我们得到了一个实现了 ColourProvider 接口的 Adaptor,现在可以把它跟 ViewPagerTrigger 一起使用了:

在setupViewPager()中,我们先创建了一个 RainbowPagerAdapter 实例,并把它应用到 ViewPager 上,然后又创建了一个加亮 FAB 背景色的 TintFilter, 以及与 ViewPager 和 Adaptor 相关联的 Trigger。

接着以同样的方式再创建一个 Prism 实例,这次我们为 Prism 绑定了更多的组件,并添加了刚才做好的 Trigger。你可能注意到 ViewPager 实例被设置了颜色,这会改变 ViewPager 滑动到边界时产生的发光效果的颜色(因为不同版本的系统会用不同的方式来处理发光效果,但 Prism 内部会处理好这些差异)。

然后把 TabLayout 和 ViewPager 进行绑定(TabLayout 要求这样做,但 Prism 并不需要这样),最后把 ViewPager 的初始页面设为第一页。好了大功告成,现在主题色会随着标签页的切换而改变,请看 Demo:

细心的人可能会发现其间的颜色过渡看起来并不生硬,颜色是随着用户的拖拽而逐渐产生变化:

还有一些更微妙的细节。如果用户选择了间隔很远的标签页面,正常情况会过渡显示从开始到结束标签之间的每种颜色,从视觉上说会略显唐突和不自然,而 ViewPagerTrigger 只选择开始和结束标签的两种颜色来做平滑过渡(也就是黄色 YELLOW 和紫色 VIOLET,跳过 GREEN、BLUE 和 INDIGO):

这是 ViewPager 滑动到边界时的动画效果:

最后我们来说一下 prism-palette的用法。先将它做为依赖添加到项目中来,对应的 build.gradle 内容如下:

PaletteTrigger 使用起来非常简单,只要创建一个 PaletteTrigger 实例,再把它添加到 Prism.Builder 上:

接下来,我们可以通过调用 PaletteTrigger 的setBitmap(Bitmap bitmap)方法来触发颜色变化。这会创建一个新的 Palette 实例,等到 Palette 从图像中提取完色样后就去触发 Prism。

要想正确地为相关联的 UI 组件着色,我们需要了解 Palette 的工作原理。

Palette 可以从一张图片中提取出最多 6 种不同的色样:

鲜艳

鲜艳浓

鲜艳淡

柔色

柔色浓

柔色淡

每种色样又可以分离出 3 种色值:

FilterdarkVibrantTitle = paletteTrigger.getDarkVibrantFilter(paletteTrigger.getTextFilter());

在上面的示例中我们实际并没绑定 UI,只是演示一下怎样提取各种色样以及如何应用。但根据前面讲过的内容,相信加入绑定也不是难事。

【重要提示】由于代码版权问题,Prism 的开发计划已无限期搁置,具体说明请参考 中的 README 内容。之所以仍然要发布这篇文章,是想让大家了解到 Prism 现有的功能,对自己的开发有所帮助。

原文链接:

转载自:

看完本文有收获?请分享给更多人

Java和Android架构

公众号:JANiubility返回搜狐,查看更多

责任编辑:

android主题切换框架,Prism(棱镜)——一款优秀的Android 主题动态切换框架相关推荐

  1. 多文档程序 两个menu框架_汇总9款优秀的开源小程序UI框架

    卧槽这玩意儿写的这么烂,我可以写一个更烂的来恶心作者--开源社区,经典语录 随着小程序日渐火爆,各种不同类型的小程序也渐渐更新,其中不乏一些优秀好用的框架/组件库. 布莱恩特:Github优秀的小程序 ...

  2. android手机 垃圾箱,Dumpster Pro「回收站」v3.6.386 for Android 直装解锁高级版 —— 一款不错的 Android 垃圾箱 / 回收站应用...

    Dumpster Pro「Android 垃圾箱.回收站」是一款不错的 Android 回收站应用,适合经常意外删除设备文件和图片的用户.下载安装本数据恢复应用后,用户就能轻松还原和恢复设备数据.而且 ...

  3. Android一步一步实现一款实用的Android广告栏

    源码:BannerLayoutDemo 有图有真相: bannerLayoutDemo 开源界有一句很有名的话叫"不要重复发明轮子",当然,我今天的观点不是要反驳这句话,轮子理论给 ...

  4. 26款优秀的Android逆向工程工具

    转自:点http://www.freebuf.com/sectool/111532.html 工欲善其事必先利其器,好的Android逆向工程工具在逆向破解工程中起到事半功倍的作用. 1. SMALI ...

  5. 三星 android n 主体,三星GalaxyS6等多款手机升级Android N需到年底

    原标题:三星GalaxyS6等多款手机升级Android N需到年底 谷歌I/O上安卓N都有哪些优势? 这次全新的Android N系统累积拥有250项全新的更新,相比上一代Android 6.0不仅 ...

  6. 6款优秀的量化交易回测框架!VNPY位居第一

    一个策略从想法,到测试,在到实盘,然后改进,进入另一个循环,需要很多的时间和精力.这时候选择一款高效.灵活的测试系统就是当务之急了.即使最后你可能需要写自己的系统,但是这些框架的软工架构还是很值得借鉴 ...

  7. android平板装虚荣windows,纠结!两款优秀的二合一平板的艰难选择

    原标题:纠结!两款优秀的二合一平板的艰难选择 说到二合一平板电脑,大家往往都会想到微软的Surface系列.不错,Surface作为二合一设备的开山鼻祖,抛砖引玉的同时开创了二合一时代.作为二合一设备 ...

  8. Android10文件管理,10款优秀的Android文件管理器

    本文将介绍10款Android文件管理器,包括:ES File Explorer.Dual File Manager XT.ASTRO File Manager,Ghost Commander,Fil ...

  9. 推荐10款优秀的JavaScript Web UI库 框架和套件

    在进行Web开发时,并非所有的库都适合你的项目,但真正开发的时候,你任然需要依赖一款UI框架.特别在你时间紧迫的时候,它是你忠实的朋友. 他们都是些广泛使用包含不同语言实现的WEB UI框架.今天我就 ...

  10. android+创意方案,有创意≠购买欲 - 10款失败的 Android 创意产品

    在手机厂商的眼中,如何迎合消费者的喜好来提升手机销量是一件非常重要的事情,而这并不容易做到.Android 领域发展至今,具备新鲜的设计理念.功能的产品不在少数,可是这些产品中很少能让消费者产生购买的 ...

最新文章

  1. 多线程编程有什么用途_C++ 多线程编程 (一)
  2. wordpress中文乱码处理方法
  3. 来自95后的天池中间件大赛总结
  4. 图形图像处理_c/c++
  5. .net通过一般处理程序模拟用户控件数据保持、Ispostback 【第二版将html与ashx文件分开】...
  6. Python 3.9,来了!
  7. 转:EXCEL数据有效性设置
  8. TIM怎么更新版本 TIM检查更新版本教程
  9. 程序员如何探索新技术
  10. CVPR2021全新Backbone | ReXNet在CV全任务以超低FLOPs达到SOTA水平
  11. glibc升级失败及处理过程
  12. Unity粒子特效UI层级问题
  13. Ubuntu虚拟机下载app网速太慢
  14. RecyclerView或是ListView(列表)点击某个条目保持选中【非常巧妙】
  15. 如何成就一个小而美的存储科技公司?
  16. Latex修改局部字体大小
  17. 关于Maven中pom文件标签的详解,分别对比父工程pom文件与子工程pom文件。
  18. linux 定时开关机
  19. 【原创】如何判断Win10计算机的硬盘是HHD还是SSD
  20. 初学者python总结

热门文章

  1. 刘强东的敌与友:嘲讽王健林一亿小目标,性侵案后李国庆说该原谅
  2. Rasa原文-生成NLU数据
  3. esp32测试wifi速率
  4. STM32MP1开发环境搭建
  5. LOJ#2538. 「PKUWC2018」Slay the Spire
  6. 请编程序将“China“译成密码,密码规律是:用原来的字母后面第4个字母代替原来的字母
  7. 49个excel常用技巧(一)
  8. php写前端还是nodejs,javascript - 新手想在短期内写一个个人博客,是用php还是用nodejs?...
  9. ila、dbg_hub、jatg时钟关系
  10. python小玩意——性格测试