黑马程序员技术交流社区

标题: 安卓着色器(tint)使用实践 [打印本页]

作者: lizhenzhen    时间: 2016-6-2 10:02
标题: 安卓着色器(tint)使用实践
1
学习tint的目的

tint可以帮助我们一张图实现各种变色,也就是说可以非常容易改变某个icon的颜色,同样的也能减少我们apk的体积(原本需要多张图片的,现在可能一张就够了)。

该图为tint效果图:
图片来源http://andraskindler.com/blog/2015/tinting_drawables


对于学习tint,我们有两个目的:


2
一张矢量图适配所有颜色
   
如何在代码中实现下图效果




方法很简单直接看代码



一个为原图效果,一个通过android:tint="@color"改变了颜色。
至于原理不做过多说明,有兴趣看看源码比较简单,也可以参考一下官网或者下面这篇文章:

https://segmentfault.com/a/1190000003038675?_ea=281641



DrawableCompat类:

是Drawable的向下兼容类,我们为了在6.0一下兼容tint属性而使用的,有兴趣的看看源码哦,也是很简单的一个兼容类。


恩,目的一基本完成了,我们来看目的二。

3更优雅的实现selector   
为了更加优雅的使用selector可谓是踩了很多坑啊,但是实践才是检验真理的唯一标准,遇到坑就多去看看源码。

以前使用selector是这样的:



所以咯,我们需要在mipmap中放置两张图片。

但是目的一中我们知道一张矢量图是能适配出所有颜色的。所以我们开始踩坑。

我们可以在color中定义一个selector,然后设置tint属性。

目的为了实现点击图标换色的效果。

3.1 第一次尝试
color/icon.xml


设置后你会发现,并没有效果啊!这是为什么呢,我们看看BitmapDrawable源码吧。


DEBUG发现updateTintFilter()方法已经执行,为什么没有效果呢?
进一步DEBUG发现界面未刷新,invalidateSelf()方法未调用,ImageView的onDraw()方法未执行,所以Drawable的draw()方法也未执行。所以暂时这种方法是行不通的。

3.2 第二次尝试
于是我们使用StateListDrawable,那么先在xml中试试可行性吧。



我们在drawable目录下icon.xml中两种状态都设置的同一张图。
恩,到这里你就会惊人的发现,效果出来了(点击切换颜色)!




但是很遗憾6.0以下会直接crash的,因为不兼容,所以我们为了兼容性,可以考虑在java代码中设置。

按照这个思路撸出代码。


代码是不是看起来还挺复杂,不过在通过代码编写selector时都是类似上面的代码,还是值得研究一番。

恩,效果出来了,具体为什么可以去看看StateListDrawable源码,然后自己DEBUG一下。

到这里踩坑完成了。更优雅的实现selector,既减少了apk大小又节约了内存。

最后总结下,默认情况下(积极使用AppCompatActivity)tint属性是兼容低版本的,而通过selector的方式只能在高版本中有效果,所以我们给出了代码去创建selector以保证其能够对低版本进行适配。

这里会不会有疑问,android:tint怎么做到兼容低版本呢?该文探究 LayoutInflater setFactory给出了解释。


作者: lizhenzhen    时间: 2016-6-2 10:03
由于原文图片无法引用,附原文地址:http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820326&idx=1&sn=7f741d29f156af6db7c37623f9e8ca4c&scene=0#wechat_redirect




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2