记一次svg的踩坑过程

1,990 阅读2分钟

起因

测试的过程中发现这样一个bug,设置的按钮在Android6.0上表现很奇怪

正常情况下应为

但是在Android6.0上显示为了

于是开启了苦逼的排查过程

失败的尝试

在刚开始的时候,因为不是很了解gradle里vectorDrawables.useSupportLibrary = true这一行配置的实际意义,所以以为是参数的配置问题,凑巧的是,在把这个参数设置为false之后,也确实没有问题了。

但是,在查阅了官方文档之后,发现是这样的,Android5.0之前不支持SVG,因此在编译的时候会把我们导入的向量文件给转化成png来达到兼容的效果。

来做个验证,设置vectorDrawables.useSupportLibrary = false

现在我们只有一个叫ic_settings的矢量图xml文件

在运行assemble之后,查看apk文件的资源

果然是把我们的矢量图给转换成了png

设置设置vectorDrawables.useSupportLibrary = true

发现xml文件还是被保留了下来

所以结论:通过设置vectorDrawables.useSupportLibrary = false的方式虽然可以解决这个问题,但是会把我们的矢量图都转为png,这无疑成本太大。

再次尝试

既然上边的思路不行,我们就换一个新的思路,先定位复现的情景,再进行分析。

经过尝试,发现在Android6.0及以下才有这个问题,从Android7.0开始的手机都没有复现这个问题。

之后就自然而然的想到了是不是Android源码上有什么变更导致的。我们对比一下VectorDrawable在6.0和7.0的差异,果然找到了一个很可疑的地方

看一下内容

Sets the fillType for a path. It is the same as SVG's "fill-rule" properties.
For more details, see https://www.w3.org/TR/SVG/painting.html#FillRuleProperty

看起来是Android7.0的时候才新增了对fillType的支持

然后看看我们的svg文件

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="54dp"
    android:viewportWidth="50"
    android:viewportHeight="54">
    <path
        android:fillAlpha="0.8"
        android:fillColor="#000000"
        android:fillType="evenOdd"
        android:pathData="M0,19.5417C0,17.152 0,15.9572 0.3512,14.8907C0.6618,13.9472 1.1698,13.0806 1.8412,12.3485C2.6001,11.5211 3.6426,10.9373 5.7276,9.7697L5.7276,9.7697L19.5276,2.0417L19.5277,2.0417C21.5242,0.9236 22.5225,0.3645 23.5805,0.1454C24.5169,-0.0485 25.4831,-0.0485 26.4195,0.1454C27.4775,0.3645 28.4758,0.9236 30.4724,2.0417L44.2724,9.7697C46.3574,10.9373 47.3999,11.5211 48.1588,12.3485C48.8302,13.0806 49.3382,13.9472 49.6488,14.8907C50,15.9572 50,17.152 50,19.5417V34.4125C50,36.8022 50,37.9971 49.6488,39.0636C49.3382,40.0071 48.8302,40.8737 48.1588,41.6057C47.3999,42.4332 46.3574,43.017 44.2724,44.1846L44.2724,44.1846L30.4724,51.9126L30.4723,51.9126C28.4758,53.0307 27.4775,53.5897 26.4195,53.8088C25.4831,54.0027 24.5169,54.0027 23.5805,53.8088C22.5225,53.5897 21.5243,53.0307 19.5278,51.9127L19.5277,51.9126L19.5276,51.9126L5.7277,44.1846C3.6426,43.017 2.6001,42.4332 1.8412,41.6057C1.1698,40.8737 0.6618,40.0071 0.3512,39.0636C0,37.9971 0,36.8022 0,34.4125V19.5417ZM5,17.8692C5,17.1807 5,16.8365 5.1018,16.5298C5.1918,16.2585 5.339,16.0096 5.5333,15.8C5.753,15.563 6.0546,15.3971 6.6579,15.0653L23.4579,5.8253C24.021,5.5156 24.3025,5.3607 24.6004,5.3C24.8641,5.2462 25.1359,5.2462 25.3996,5.3C25.6975,5.3607 25.979,5.5156 26.5421,5.8253L43.3421,15.0653C43.9454,15.3971 44.247,15.563 44.4667,15.8C44.661,16.0096 44.8082,16.2585 44.8982,16.5298C45,16.8365 45,17.1807 45,17.8692V36.0851C45,36.7735 45,37.1177 44.8982,37.4245C44.8082,37.6958 44.661,37.9447 44.4667,38.1543C44.247,38.3913 43.9454,38.5572 43.3421,38.889L26.5421,48.129L26.5421,48.129C25.979,48.4387 25.6974,48.5935 25.3996,48.6543C25.1359,48.708 24.8641,48.708 24.6004,48.6543C24.3026,48.5935 24.021,48.4387 23.4579,48.129L23.4579,48.129L6.6579,38.889C6.0546,38.5572 5.753,38.3913 5.5333,38.1543C5.339,37.9447 5.1918,37.6958 5.1018,37.4245C5,37.1177 5,36.7735 5,36.0851V17.8692ZM37,26.9771C37,33.6045 31.6274,38.9771 25,38.9771C18.3726,38.9771 13,33.6045 13,26.9771C13,20.3496 18.3726,14.977 25,14.977C31.6274,14.977 37,20.3496 37,26.9771ZM32,26.9771C32,30.843 28.866,33.9771 25,33.9771C21.134,33.9771 18,30.843 18,26.9771C18,23.1111 21.134,19.9771 25,19.9771C28.866,19.9771 32,23.1111 32,26.9771Z" />
</vector>

果然用到了android:fillType这个属性

然后我们把fillType设为nonZero

boom!破案了!

总结

出现这个问题的原因是Android在7.0之前不支持fillType属性导致的,因此不是说Android5.0之后的机型都能完美支持矢量图。有些属性是后来才逐步支持的。

对于这种情况,还是老老实实的用图片吧!