📜 ⬆️ ⬇️

Vector pictures with gradient in Android 5.0

It turned out that in my current project I had to face a problem. The designer agreed with the customer a set of icons, painted with a simple linear gradient. And she sent me these icons in svg format, with a sense of accomplishment. Googling revealed that support for gradients in vector drawable only starts with the SDK 24+.

Nevertheless, using a small trick, it was possible to get around the limitation, which I will demonstrate with an example.

As a working picture, take the following:
')

Source:

<svg width="980px" height="980px" viewBox="10 10 980 980" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch --> <desc>Created with Sketch.</desc> <defs> <linearGradient x1="0%" y1="0%" x2="101.999998%" y2="100.999999%" id="linearGradient-1"> <stop stop-color="#2CF607" offset="0%"></stop> <stop stop-color="#038BF3" offset="100%"></stop> </linearGradient> </defs> <path d="M328.5,353 C369.1,353 402,320.1 402,279.5 C402,238.9 369.1,206 328.5,206 C287.9,206 255,238.9 255,279.5 C255,320.1 287.9,353 328.5,353 Z M500,10 C229.4,10 10,229.4 10,500 C10,770.6 229.4,990 500,990 C770.6,990 990,770.6 990,500 C990,229.4 770.6,10 500,10 Z M500,941 C256.5,941 59,743.6 59,500 C59,256.4 256.5,59 500,59 C743.5,59 941,256.4 941,500 C941,743.6 743.5,941 500,941 Z M671.5,353 C712.1,353 745,320.1 745,279.5 C745,238.9 712.1,206 671.5,206 C630.9,206 598,238.9 598,279.5 C598,320.1 630.9,353 671.5,353 Z M720.5,598 C720.5,598 637.8,745 500,745 C362.2,745 279.5,598 279.5,598 C233.4,572.2 189.2,624.9 230.5,671.5 C230.5,671.5 325.4,818.5 500,818.5 C674.6,818.5 769.5,671.5 769.5,671.5 C808.3,616.3 762.5,570.4 720.5,598 Z" id="Shape" stroke="none" fill="url(#linearGradient-1)" fill-rule="nonzero"></path> </svg> 

We are trying to import the original image in Android Studio.

 In smile.svg: ERROR@ line 5 <defs> is not supported ERROR@ line 11 Unsupported URL value: url(#linearGradient-1) ERROR@ line 11 Unsupported URL value: url(#linearGradient-1) 

Which was to be expected.

Remove the defs section and replace the fill attribute with some color. The parameters of the gradient stops are memorized, we will need them later. Now the studio does not mind.

Our resulting vector drawable:


 <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="980dp" android:height="980dp" android:viewportWidth="980.0" android:viewportHeight="980.0"> <path android:pathData="M318.5,343C359.1,343 392,310.1 392,269.5C392,228.9 359.1,196 318.5,196C277.9,196 245,228.9 245,269.5C245,310.1 277.9,343 318.5,343ZM490,0C219.4,0 0,219.4 0,490C0,760.6 219.4,980 490,980C760.6,980 980,760.6 980,490C980,219.4 760.6,0 490,0ZM490,931C246.5,931 49,733.6 49,490C49,246.4 246.5,49 490,49C733.5,49 931,246.4 931,490C931,733.6 733.5,931 490,931ZM661.5,343C702.1,343 735,310.1 735,269.5C735,228.9 702.1,196 661.5,196C620.9,196 588,228.9 588,269.5C588,310.1 620.9,343 661.5,343ZM710.5,588C710.5,588 627.8,735 490,735C352.2,735 269.5,588 269.5,588C223.4,562.2 179.2,614.9 220.5,661.5C220.5,661.5 315.4,808.5 490,808.5C664.6,808.5 759.5,661.5 759.5,661.5C798.3,606.3 752.5,560.4 710.5,588Z" android:strokeColor="#00000000" android:fillColor="#00ff00"/> </vector> 

The next step is to make the picture “negative”, i.e. color areas convert to transparent, and everything else to make the background color, in our simplest example, white. To do this, it is enough to add only one framing contour to the path (theoretically, it may be necessary to change the direction of the walk to the opposite one). At the same time, I completely removed android: strokeColor and replaced fillColor with white:


 <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="980dp" android:height="980dp" android:viewportWidth="980.0" android:viewportHeight="980.0"> <path android:pathData="M0,0L980,0L980,980L0,980 M318.5,343C359.1,343 392,310.1 392,269.5C392,228.9 359.1,196 318.5,196C277.9,196 245,228.9 245,269.5C245,310.1 277.9,343 318.5,343ZM490,0C219.4,0 0,219.4 0,490C0,760.6 219.4,980 490,980C760.6,980 980,760.6 980,490C980,219.4 760.6,0 490,0ZM490,931C246.5,931 49,733.6 49,490C49,246.4 246.5,49 490,49C733.5,49 931,246.4 931,490C931,733.6 733.5,931 490,931ZM661.5,343C702.1,343 735,310.1 735,269.5C735,228.9 702.1,196 661.5,196C620.9,196 588,228.9 588,269.5C588,310.1 620.9,343 661.5,343ZM710.5,588C710.5,588 627.8,735 490,735C352.2,735 269.5,588 269.5,588C223.4,562.2 179.2,614.9 220.5,661.5C220.5,661.5 315.4,808.5 490,808.5C664.6,808.5 759.5,661.5 759.5,661.5C798.3,606.3 752.5,560.4 710.5,588Z" android:fillColor="#ffffff"/> </vector> 

The first part of the work has been done, it now remains to create a two-layered shape with a gradient, and in the top layer put our picture:

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:top="0.5dp" android:right="0.5dp" android:left="0.5dp" android:bottom="0.5dp"> <shape android:shape="rectangle"> <gradient android:startColor="#2CF607" android:endColor="#038BF3" android:angle="135" android:type="linear" /> <size android:width="64dp" android:height="64dp"> </size> </shape> </item> <item android:drawable="@drawable/ic_smile" /> </layer-list> 

I needed the half pixel indentation to get rid of the artifacts that were visible when I placed the image in the layout.

The result is quite decent (only I accidentally swapped startColor and endColor, but I don’t want to redo it):


Enjoy your coding!

Source: https://habr.com/ru/post/325464/


All Articles