A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lizhenzhen 中级黑马   /  2016-6-2 10:02  /  1344 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1
学习tint的目的

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

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


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

  • 矢量图适配所有颜色(妈妈再也不要担心我找图了)。
  • 更优雅的selector实现方式。


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



  • 方法一:xml


方法很简单直接看代码



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

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

  • 方法二:代码实现



DrawableCompat类:

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

  • wrap方法:使用tint就必须调用该方法对Drawable进行一次包装。
  • mutate方法:(个人简单的理解就是类似于对象的深拷贝与浅拷贝),如果不调用该方法,我们进行操作的就是原drawable,着色之后原drawable也改变的,所有两个ImageView都会显示着色之后的drawable。调用mutate后会对ConstantState进行一次拷贝,详情可看源码,或者参考该文:
    http://www.race604.com/tint-drawable/ 。


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

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给出了解释。

1 个回复

倒序浏览
由于原文图片无法引用,附原文地址:http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820326&idx=1&sn=7f741d29f156af6db7c37623f9e8ca4c&scene=0#wechat_redirect
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马