18

I'm having problems with the VectorDrawables introduced by the support library.

Looking around, I read about similar issues regarding bad scaling or incorrect preview in Android Studio. Well, my problem is unluckily different.

PROBLEM:

In fact, my VectorDrawable renders perfectly in the Android Studio preview but gets messed up at runtime on device (Android v. 5.1.1 and 6.0).

EXPORTING:

Starting from an SVG file (with only one compounded path), I imported it with the Android Studio tool (but I also tried many other tools to convert it). The file was made in the same way as a bunch of others, though only some render bad.

WHAT I ALREADY TRIED:

I tried to set it in an imageview with app:srcCompat (even with src:). I tried to use it in a menu (directly setting the icon, or using a selector).

SVG CODE:

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 626.96 610.53"><title>PATHOLOGIES</title><path d="M5766.55,588.54a54.73,54.73,0,0,0-4.23-3.81,248.33,248.33,0,0,0,31.34-121.54c-0.23-138.68-114.72-251.15-253.38-249-134.71,2.07-243.52,110.91-245.54,245.64a249.48,249.48,0,0,0,390.59,209.52l0.21,0.22,155.12,155.12,81-81Zm-222.36,64.92c-104.85,0-189.85-85-189.85-189.85s85-189.85,189.85-189.85S5734,358.76,5734,463.61,5649,653.46,5544.19,653.46ZM5452,347.1l7.72-22.08a161.29,161.29,0,0,1,52.5-20.55l-19.84,56.75A19.25,19.25,0,0,1,5467.83,373l-4-1.41A19.25,19.25,0,0,1,5452,347.1Zm20.13,82.62L5430,502.57a19.25,19.25,0,0,1-26.29,7l-3.71-2.14a19.25,19.25,0,0,1-7-26.29L5435,408.33a19.25,19.25,0,0,1,26.29-7l3.71,2.14A19.25,19.25,0,0,1,5472.1,429.72Zm-82.73-14.9A161.59,161.59,0,0,1,5408.85,374l9.06,9.06a19.25,19.25,0,0,1,0,27.22l-3,3A19.24,19.24,0,0,1,5389.37,414.82Zm151.76-54A19.25,19.25,0,0,1,5552,335.85l55.51-21.72a162.36,162.36,0,0,1,43.87,27.64A19.17,19.17,0,0,1,5646,345l-78.34,30.65a19.25,19.25,0,0,1-24.94-10.91Zm-13.43,29.12,66.74,51.21a19.25,19.25,0,0,1,3.55,27l-2.61,3.4a19.25,19.25,0,0,1-27,3.55l-66.74-51.21a19.25,19.25,0,0,1-3.55-27l2.61-3.4A19.25,19.25,0,0,1,5527.69,389.91Zm83.57,191.47-2.82,3.23a19.25,19.25,0,0,1-27.15,1.86l-63.41-55.28A19.25,19.25,0,0,1,5516,504l2.82-3.23a19.25,19.25,0,0,1,27.16-1.86l63.41,55.28A19.25,19.25,0,0,1,5611.26,581.38Zm60.09-191.15,4,1.59a19.25,19.25,0,0,1,10.71,25l-31.28,78.09a19.25,19.25,0,0,1-25,10.71l-4-1.59A19.25,19.25,0,0,1,5615,479l31.28-78.09A19.25,19.25,0,0,1,5671.34,390.24ZM5504.73,604.39a19.19,19.19,0,0,1-4.85,15.4,161.36,161.36,0,0,1-38.43-16.53l-9.92-76.83a19.25,19.25,0,0,1,16.62-21.55l4.25-.55A19.25,19.25,0,0,1,5494,521ZM5686.4,538L5685,544.4a163.11,163.11,0,0,1-56.5,57.93l16.12-73.51a19.25,19.25,0,0,1,22.92-14.68l4.19,0.92A19.25,19.25,0,0,1,5686.4,538Z" transform="translate(-5294.72 -214.14)"/></svg>

VECTORDRAWABLE CODE:

<vector android:height="24dp" android:viewportHeight="610.53"
android:viewportWidth="626.96" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M471.8,374.4a54.7,54.7 0,0 0,-4.2 -3.8,248.3 248.3,0 0,0 31.3,
-121.5c-0.2,-138.7 -114.7,-251.1 -253.4,-249 -134.7,2.1 -243.5,110.9 -245.5,245.6a249.5,249.5 0,0 0,390.6 209.5l0.2,
0.2 155.1,155.1 81,-81ZM249.5,439.3c-104.8,0 -189.9,-85 -189.9,-189.9s85,-189.9 189.9,-189.9S439.3,144.6 439.3,
249.5 354.3,439.3 249.5,439.3ZM157.3,133l7.7,-22.1a161.3,161.3 0,0 1,52.5 -20.5l-19.8,56.8A19.3,19.3 0,0 1,
173.1 158.9l-4,-1.4A19.3,19.3 0,0 1,157.3 133ZM177.4,215.6L135.3,288.4a19.3,19.3 0,0 1,-26.3 7l-3.7,-2.1a19.3,
19.3 0,0 1,-7 -26.3L140.3,194.2a19.3,19.3 0,0 1,26.3 -7l3.7,2.1A19.3,19.3 0,0 1,177.4 215.6ZM94.7,200.7A161.6,
161.6 0,0 1,114.1 159.9l9.1,9.1a19.3,19.3 0,0 1,0 27.2l-3,3A19.2,19.2 0,0 1,94.6 200.7ZM246.4,146.7A19.3,19.3 0,
0 1,257.3 121.7l55.5,-21.7a162.4,162.4 0,0 1,43.9 27.6A19.2,19.2 0,0 1,351.3 130.9l-78.3,30.6a19.3,19.3 0,0 1,
-24.9 -10.9ZM233,175.8 L299.7,227a19.3,19.3 0,0 1,3.5 27l-2.6,3.4a19.3,19.3 0,0 1,-27 3.5l-66.7,-51.2a19.3,19.3 0,
0 1,-3.5 -27l2.6,-3.4A19.3,19.3 0,0 1,233 175.8ZM316.6,367.3 L313.8,370.5a19.3,19.3 0,0 1,-27.1 1.9l-63.4,-55.3A19.3,
19.3 0,0 1,221.3 289.9l2.8,-3.2a19.3,19.3 0,0 1,27.2 -1.9l63.4,55.3A19.3,19.3 0,0 1,316.5 367.2ZM376.7,176.1 L380.7,
177.7a19.3,19.3 0,0 1,10.7 25l-31.3,78.1a19.3,19.3 0,0 1,-25 10.7l-4,-1.6A19.3,19.3 0,0 1,320.3 264.9l31.3,-78.1A19.3,
19.3 0,0 1,376.6 176.1ZM210,390.3a19.2,19.2 0,0 1,-4.8 15.4,161.4 161.4,0 0,1 -38.4,-16.5l-9.9,-76.8a19.3,19.3 0,0 1,
16.6 -21.5l4.3,-0.6A19.3,19.3 0,0 1,199.3 306.9ZM391.7,323.9L390.3,330.3a163.1,163.1 0,0 1,-56.5 57.9l16.1,-73.5a19.3,
19.3 0,0 1,22.9 -14.7l4.2,0.9A19.3,19.3 0,0 1,391.7 323.9Z"/>

As rendered on Android Studio:

As rendered on Android Studio

As rendered on device (after AndroidStudio import):

As rendered on device

I can't really figure out what's causing the bad rendering. I'm pretty sure it's not an svg problem (correct me if I'm wrong, please) since the other drawables are rendering correctly. I wouldn't even call for a library bug since I happen to be the only one experiencing the problem. What am I doing wrong?

Thanks for the help

  • This looks like the same issue as: https://stackoverflow.com/questions/38184911/vectordrawable-not-rendering-correctly-on-api-23 – steakunderscore May 22 '17 at 17:03

4 Answers4

9

In my case nothing helped until I replaced all elliptical arc commands (A) with cubic Bézier curve commands (C). Any arc could be represented with one or several Bézier curves. The whole ellipse may be replaced with four Bézier curves.

Inkscape tends to convert arcs to Bézier curves once you start editing the path in SVG, so you can use Inkscape for conversion. It looks like Android vector renderer has a serious issues in processing A/a commands, doesn't matter if they are relative or absolute. So, just try to convert A/a => C/c.

Note that it is not enough to change command letter, you need to set control points appropriately.

Stanislav
  • 438
  • 7
  • 13
  • 2
    You saved my day, thanks. All I needed to do is: loading the SVG into Inkscape, select one point in the curve and then move one step left and one step right (back to the same position). After saving and importing it was working on older OS versions too. ("A/a" command was turned into "C/c".) – racs Nov 25 '17 at 02:12
8

Native can't display arcs, but appCompat can. So instead:

<ImageView
    android:src="@drawable/mydrawable"
/>

use

app:srcCompat="@drawable/mydrawable"

It's that simple o_O.

(app is xmlns:app="http://schemas.android.com/apk/res-auto")

Agent_L
  • 4,960
  • 28
  • 30
  • I don't know if it's working now, but at the time this was posted srcCompat was having problems with rendering as much as Native (as was stated in the question). So if anyone still has these kind of problems I guess my answer and the others could still be useful. – Francesco Ambrosini Nov 20 '18 at 11:07
  • @FrancescoAmbrosini I've posted it now because it's working now. It's the best solution, as of 2018, because it doesn't involve modifying neither the image nor the way it's displayed. Other answers give nice historical background, but are now obsolete. – Agent_L Nov 20 '18 at 11:14
4

Solution

After some more tries (and help from people), I've found the problem. The problem was with the fill-rule as other already experienced, but in the opposite way!

In fact, as far as I know, VectorDrawable uses the non-zero fill-rule and has rendering problems with SVGs exported with the evenodd rule. That's why I've always used the non-zero rule. Turns out that using the android:fillType="evenOdd" one solves my problem.

I don't know why, and at this point I'm too afraid to ask.

Tomas
  • 1,567
  • 3
  • 21
  • 38
  • This tool should solve your problem http://a-student.github.io/SvgToVectorDrawableConverter.Web/ – A-student Oct 10 '16 at 18:00
  • 1
    From your screenshot I don't think it is fill problem as it looks like some parts (points) in path are being ignored. I think Paul is correct. – AaA Aug 15 '17 at 07:22
2

I suspect it is to do with path command parsing. If we look at the first subpath of your path (which is the one not being draw correctly), it looks like the following:

M 471.8, 374.4
a 54.7, 54.7 0, 0 0, -4.2 -3.8,
  248.3 248.3, 0 0, 0 31.3,-121.5
c -0.2, -138.7 -114.7, -251.1 -253.4, -249
  -134.7, 2.1 -243.5, 110.9 -245.5, 245.6
a 249.5, 249.5 0, 0 0, 390.6 209.5
l 0.2, 0.2
  155.1, 155.1
  81, -81Z

I've broken it down for readability.

You can see that it is using one of the features of SVG paths command strings, where if a path command is repeated, you can skip it and just provide the coordinates. It's doing it here for the a (arc), c (curve) and l (line) commands.

While the line segments (forming the handle) seem to be rendering okay, I suspect that the VectorDrawable renderer is not parsing the arc and/or the curve segments properly. However I haven't looked at the Android codebase to confirm the bug.

I would suggest you try putting the skipped path command characters back in to the path, to see if it works better. For example:

M 471.8, 374.4
a 54.7, 54.7 0, 0 0, -4.2 -3.8
a 248.3 248.3, 0 0, 0 31.3,-121.5
c -0.2, -138.7 -114.7, -251.1 -253.4, -249
c -134.7, 2.1 -243.5, 110.9 -245.5, 245.6
a 249.5, 249.5 0, 0 0, 390.6 209.5
l 0.2, 0.2
  155.1, 155.1
  81, -81Z

There is another sub-path later in the string (corresponding to one of the "pills"), that also uses the repeated coords shortcut. If we modify that also, the resulting VectorDrawable looks like:

<vector android:height="24dp" android:viewportHeight="610.53"
android:viewportWidth="626.96" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M471.8,374.4a54.7,54.7 0,0 0,-4.2 -3.8a248.3 248.3,0 0,0 31.3,
-121.5c-0.2,-138.7 -114.7,-251.1 -253.4,-249c-134.7,2.1 -243.5,110.9 -245.5,245.6a249.5,249.5 0,0 0,390.6 209.5l0.2,
0.2 155.1,155.1 81,-81ZM249.5,439.3c-104.8,0 -189.9,-85 -189.9,-189.9s85,-189.9 189.9,-189.9S439.3,144.6 439.3,
249.5 354.3,439.3 249.5,439.3ZM157.3,133l7.7,-22.1a161.3,161.3 0,0 1,52.5 -20.5l-19.8,56.8A19.3,19.3 0,0 1,
173.1 158.9l-4,-1.4A19.3,19.3 0,0 1,157.3 133ZM177.4,215.6L135.3,288.4a19.3,19.3 0,0 1,-26.3 7l-3.7,-2.1a19.3,
19.3 0,0 1,-7 -26.3L140.3,194.2a19.3,19.3 0,0 1,26.3 -7l3.7,2.1A19.3,19.3 0,0 1,177.4 215.6ZM94.7,200.7A161.6,
161.6 0,0 1,114.1 159.9l9.1,9.1a19.3,19.3 0,0 1,0 27.2l-3,3A19.2,19.2 0,0 1,94.6 200.7ZM246.4,146.7A19.3,19.3 0,
0 1,257.3 121.7l55.5,-21.7a162.4,162.4 0,0 1,43.9 27.6A19.2,19.2 0,0 1,351.3 130.9l-78.3,30.6a19.3,19.3 0,0 1,
-24.9 -10.9ZM233,175.8 L299.7,227a19.3,19.3 0,0 1,3.5 27l-2.6,3.4a19.3,19.3 0,0 1,-27 3.5l-66.7,-51.2a19.3,19.3 0,
0 1,-3.5 -27l2.6,-3.4A19.3,19.3 0,0 1,233 175.8ZM316.6,367.3 L313.8,370.5a19.3,19.3 0,0 1,-27.1 1.9l-63.4,-55.3A19.3,
19.3 0,0 1,221.3 289.9l2.8,-3.2a19.3,19.3 0,0 1,27.2 -1.9l63.4,55.3A19.3,19.3 0,0 1,316.5 367.2ZM376.7,176.1 L380.7,
177.7a19.3,19.3 0,0 1,10.7 25l-31.3,78.1a19.3,19.3 0,0 1,-25 10.7l-4,-1.6A19.3,19.3 0,0 1,320.3 264.9l31.3,-78.1A19.3,
19.3 0,0 1,376.6 176.1ZM210,390.3a19.2,19.2 0,0 1,-4.8 15.4a161.4 161.4,0 0,1 -38.4,-16.5l-9.9,-76.8a19.3,19.3 0,0 1,
16.6 -21.5l4.3,-0.6A19.3,19.3 0,0 1,199.3 306.9ZM391.7,323.9L390.3,330.3a163.1,163.1 0,0 1,-56.5 57.9l16.1,-73.5a19.3,
19.3 0,0 1,22.9 -14.7l4.2,0.9A19.3,19.3 0,0 1,391.7 323.9Z"/>

Try that and see if it works any better.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Thanks for the answer! However, I tried the xml you provided and it didn't have any effect on the rendering. Did you modify the android path or the svg one and then converted it? Maybe the AndroidStudio importer itself is not recognizing the skipped commands, so it would be nice to try to modify the svg file before converting it (if this is not what you have already done). Let me know what you think! – Francesco Ambrosini Mar 12 '16 at 11:41
  • 1
    I modified the VectorDrawable. I doubt modifying the SVG would make any difference. It was a hunch that was wrong I guess. – Paul LeBeau Mar 12 '16 at 11:45
  • 1
    You are absolutely right. for my drawing I just needed to include on line (l) tag to fix it. However finding the culprit in a complex SVG is like finding a needle in a stack of needle. in `inkscape` in SVG output settings, make sure to check Force repease command and select Path string format as absolute. – AaA Aug 15 '17 at 07:06