为毛矢量图图标还发虚?

作者: rain 分类: 移动 发布时间: 2016-06-04 11:10 6 条评论

矢量图(SVG)在 Android 系统中通过 VectorDrawable 来使用。而 Android 系统提供的 VectorDrawable 和 AnimatedVectorDrawable 很好很强大。但是为毛我在使用 VectorDrawable 图标的时候,发现图标发虚了呢? 图标被放大了,不是说好的矢量图可以自由放大缩小而不发虚吗?还让不让宝宝开心过六一了!?

要分析这个原因,就需要看看 VectorDrawable 和 ImageView 的相关代码了。

VectorDrawable.java 的 draw 函数中,先获取这个 Drawable 的大小 (final Rect bounds = getBounds();) ,然后矢量图根据这个尺寸来绘制图形,这样绘制的图形是不会发虚的。

所以可以看到问题不是出现在 VectorDrawable 中,再来看看 ImageView:

ImageView.java

在 ImageView 的 configureBounds 函数中,根据 View 的大小来修改了图片大小,但是具体如何修改的,是由 ScaleType 来决定的:

上面的代码中,如果 scaleType 为 ScaleType.FIT_XY,则直接修改 Drawable 的 bounds :

而其他情况,是由 ImageView 自己通过 mMatrix 来缩放 mDrawable 的。也就是说,如果你的 ImageView 的scaleType 不是 ScaleType.FIT_XY,并且 矢量图的原本尺寸不是 0 的话(矢量图的原本尺寸在 xml 中定义,是不会为 0 的, 如果为 0 则在运行的时候会出现矢量图解析错误: Binary XML file line #1 tag requires width > 0 ),则 ImageView 先通过矢量图原来的大小来得到一个图标,然后自己把这个图标通过 mDrawMatrix 的方式来缩放,所以最终绘制的图标就是被缩放过的图标了。 而 ImageView 的 ScaleType 的默认值为 ScaleType.FIT_CENTER ,这样就发现导致图标发虚的罪魁祸首了。解决方式很简单:
只需要设置 ImageView 的 ScaleType 为 ScaleType.FIT_XY 即可。

如果你无法修改这个类型,咋办?

如果是这样的情况,你只能采用效率低点的办法了,修改 矢量图中的尺寸定义,把图标的宽度和高度修改为比较大的值,这样可以保证 ImageView 只是缩小图标而不会放大图标,从而避免由于放大图标导致的图标发虚的问题:

PS: 这个发虚的问题应该是 Android 系统的bug。

本文出自 云在千峰,转载时请注明出处及相应链接。

本文永久链接: http://blog.chengyunfeng.com/?p=999

Ɣ回顶部