What are the best practices for using SVG badges on Android?

I am going to create my first Android native (and not browser-based) application and look for some good practices regarding icon creation / creation. Since it needs to support multiple devices / permissions, I thought it was best to use SVG to create them. There is at least this lib: http://code.google.com/p/svg-android/ that promises offers SVG support on Android.

So far, I have not found resources describing the use of this or another library as a means to display SVG icons on a device, so I'm a little reluctant to use it. The best I've seen so far is to use SVG as a source format for pre-rendering png-based icons in different resolutions.

So, my questions are: Are SVG icons a good option for direct use on a device without a preliminary png rendering step (actually it works), and if, why doesn't anyone use this approach?

+64
android svg icons
Mar 10 2018-12-12T00:
source share
12 answers

For Android older than Lollipop, your best practice for SVG on Android will be to use a tool to convert your SVG to PNG according to your sizes. The existing SVG support for Android is not exhaustive of what you are likely to find in the SVG file, and even if it is, support is not built into the OS, so there is certainly no use of them directly for icons.

Starting with Lollipop (API 21), see What are the best practices for using SVG icons on Android? . Thanks to @MarkWhitaker @AustynMahoney for pointing this out.

+25
Mar 10 '12 at 16:16
source share

Starting with Lollipop (API 21), Android defines the VectorDrawable class for defining drawings based on vector graphics, Android Studio 1.4 adds “Vector Asset Studio” to simplify their work, including the SVG import function and the new Gradle plugin that generates PNG versions of icons VectorDrawable at build time for API 20 and earlier. There's also a third-party tool for converting SVG to VectorDrawables . Keep in mind that although vector drawings can be defined in XML, the file format is not SVG, and not all SVG files can be successfully converted. Simple graphics, such as icons, should work fine.

If you still need to create PNG yourself, you will need to generate your icons at different resolutions . To simplify the creation of these PNGs, I create the icons as SVG and then export to various sizes using Inkscape , which is free and cross-platform. It got some useful icon-creating features, including the Preview Preview view (see below), and it generates nice clear PNGs.

enter image description here

+38
Mar 24 '15 at 9:28
source share

This is what we use to convert the SVG file to several permissions. For example, to create a startup icon: svg2png -w48 icon.svg

 #!/bin/bash -e # Transforms a SVG into a PNG for each platform # Sizes extracted from # http://developer.android.com/design/style/iconography.html [ -z $2 ] && echo -e "ERROR: filename and one dimension (-w or -h) is required, for example:\nsvg2png -w48 icon.svg\n" && exit 1; FILENAME=$2 DEST_FILENAME=`echo $2 | sed s/\.svg/\.png/` FLAG=`echo $1 | cut -c1-2` ORIGINAL_VALUE=`echo $1 | cut -c3-` if [ "$FLAG" != "-w" ] && [ "$FLAG" != "-h" ]; then echo "Unknown parameter: $FLAG" exit 1 fi # PARAMETERS: {multiplier} {destination folder} function export { VALUE=$(echo "scale=0; $ORIGINAL_VALUE*$1" | bc -l) CMD="inkscape $FLAG$VALUE --export-background-opacity=0 --export-png=src/main/res/$2/$DEST_FILENAME src/main/svg/$FILENAME > /dev/null" echo $CMD eval $CMD } export 1 drawable-mdpi export 1.5 drawable-hdpi export 2 drawable-xhdpi export 3 drawable-xxhdpi export 4 drawable-xxxhdpi 
+29
Apr 11 '14 at 14:27
source share

Good news everyone! Since android support is library 23.2 , we can use svg-s to return to API level 7 !

If you want to be backward compatible only until Lollipop (API 21) checks Mark Whitaker's answer , but if you want to go below, you need to add these lines to your build.gradle:

 // Gradle Plugin 2.0+ (if you using older version check the library announcement link) android { defaultConfig { vectorDrawables.useSupportLibrary = true } } 

Also keep in mind that:

  • instead of android:src you need to use the app:srcCompat in ImageViews.
  • you cannot use svg-s in StateListDrawables or other xml drawings, instead create them programmatically.
  • you cannot use the android:background attribute or View.setBackgroundResource() , use View.setBackground() instead.
  • you cannot use svg-s in case of notifications.
+13
Aug 10 '16 at 11:33
source share

Another option is to convert your SVG objects to TTF font type. Include the font in the application and use it that way. This does the trick for monochrome simple shapes.

There are several free conversion tools.

+6
Nov 12 '14 at 16:04
source share

Since nacho-coloma's answer helped me, I took its excellent script and made it somewhat easier to use on a daily basis.

Firstly:

  • Create a drawable-svg directory next to your res directory.
  • Put your svg and script files in drawable-svg .
  • Make the script executable.
  • Run it. In Ubuntu, you can simply double-click it in Nautilus and make it run in the terminal.

And later, when you get the new svg files:

  1. Put the new svg files in drawable-svg and run the script again.

By default, it will do what you want: scale each svg file in png files and place them in ../res/drawable-mdpi , ../res/drawable-hdpi , etc.

The script takes two parameters:

  • Scale svg file template, default: *.svg
  • The base directory for put, by default ../res/ (i.e. your res directory with the above setting).

You can experiment by scaling one svg to pngs in the current directory as follows:

 $ ./svg2png test.svg . 

Or just process all the images:

 $ ./svg2png 

I think you could place drawable-svg inside the res directory, but I haven't looked at what is wrapped in the latest APK. In addition, my svg files have - in their names that Android does not like, and my script takes care of renaming png files to something that works on Android.

I use ImageMagick for conversion, which is a bit more standard than Inkscape (although I liked the approach). Both methods are included in the script for reference.

Here's the script:

 #!/bin/bash scalesvg () { svgfile="$1" pngdir="$2" pngscale="$3" qualifier="$4" svgwidthxheight=$(identify "$svgfile" | cut -d ' ' -f 3) svgwidth=${svgwidthxheight%x*} svgheight=${svgwidthxheight#*x} pngfile="$(basename $svgfile)" # Strip path. pngfile="${pngfile/.svg/.png}" # Replace extension. pngfile="${pngfile/[^A-Za-z0-9._]/_}" # Replace invalid characters. pngfile="$pngdir/$qualifier/$pngfile" # Prepend output path. if [ ! -d $(dirname "$pngfile") ]; then echo "WARNING: Output directory does not exist: $(dirname "$pngfile")" #echo "Exiting" #exit 1 echo "Outputting here instead: $pngfile" pngfile="$qualifier-${svgfile/.svg/.png}" fi pngwidth=$(echo "scale=0; $svgwidth*$pngscale" | bc -l) pngheight=$(echo "scale=0; $svgheight*$pngscale" | bc -l) pngdensity=$(echo "scale=0; 72*$pngscale" | bc -l) # 72 is default, echo "$svgfile ${svgwidth}×${svgheight}px -> $pngfile ${pngwidth}×${pngheight}px @ $pngdensity dpi" convert -background transparent -density $pngdensity "$svgfile" "$pngfile" #inkscape -w${pngwidth} --export-background-opacity=0 --export-png="$pngfile" "$svgfile" > /dev/null #convert "$svgfile" -background transparent -scale ${pngwidth}x${pngheight} "$pngfile" } svgfiles="$1" svgfiles="${svgfiles:=*.svg}" # Default to input all *.svg in current dir. pngdir="$2" pngdir="${pngdir:=../res}" # Default to place output pngs to ../res, ie. ../res/drawable-hdpi etc. for svgfile in $svgfiles; do echo "Scaling $svgfile ..." scalesvg "$svgfile" "$pngdir" 0.75 drawable-ldpi scalesvg "$svgfile" "$pngdir" 1 drawable-mdpi scalesvg "$svgfile" "$pngdir" 1.5 drawable-hdpi scalesvg "$svgfile" "$pngdir" 2 drawable-xhdpi scalesvg "$svgfile" "$pngdir" 3 drawable-xxhdpi scalesvg "$svgfile" "$pngdir" 4 drawable-xxxhdpi done echo -n "Done." read # I've made it wait for Enter -- convenient when run from Nautilus. 
+6
Mar 08 '15 at 20:48
source share

Android Support Library 23.2 Support for vector drawings and animated vector drawings

  • add vectorDrawables.useSupportLibrary = true to the build.gradle file.
  • Use app:srcCompat="@drawable/ic_add" instead of android:src="..." or setImageResource() for your ImageView

http://android-developers.blogspot.sk/2016/02/android-support-library-232.html

+5
Jul 27 '16 at 10:30
source share

SVG icons are not a good option for direct use on the device if you need to scale them to different sizes, which usually means that you want to use the vector format in the first place. The large icon will never scale gracefully, because, well, computer displays are made of pixels. Thus, the lines of the vector image can be aligned "between pixels", creating a blurred border. In addition, large icons require more details than small icons that require very few details. The detailed icon is not very good in very small sizes, and a simple icon does not look very good when scaling to very large sizes. I recently read a wonderful article about this by a professional user interface designer: About these vector icons .

+3
Apr 21 2018-12-21T00:
source share

I just posted a script to create all the platform icons for PhoneGap applications that may be useful. However, add code to create screens.

+2
Aug 28 '14 at 2:16
source share

I was just starting to use Victor , Trello's open source library, to convert SVG files to PNG files of various required resolutions during build.

PROFI

  • You do not need to run a script or tool to create different PNG files each time you change or add an icon. (You need to click Rebuild in Android Studio when you added a new svg file or renamed an existing one).
  • There is no PNG in your source, so there is less interference.

REDD

  • The only drawback that I have seen so far is that Android Studio does not yet recognize the generated resources in XML, so you will get red warnings in your XML files, and you do not have autocomplete for your SVG-based drawings, It works great , and this problem should be fixed in a future version of Android Studio.

If you are using SVG generated by http://materialdesignicons.com/ , be sure to download the entire file or copy from the "SVG File" tab when selecting "View SVG"

+2
Jun 17 '15 at 9:20
source share

I have never managed to run Linux shell scripts in Cygwin on Windows. So here is a batch file that does what the Nacho Coloma bash script does. The small difference is that this batch file requires both input and the name of the output file, as in "svg2png -w24 input.svg output.png".

Configure the "svg" folder in the src / main project directory and copy the SVG files and this batch file to this folder according to the instructions of Stephan. Run the batch file from the svg folder. If you are using 32-bit Windows, you will most likely need to change the path to Inkscape to use "Program Files (x86)."

 @echo off echo Convert an SVG file to a PNG resource file with multiple resolutions. rem Check the arguments set temp=%1 set switch=%temp:~0,2% set pixels=%temp:~2% if not "%switch%"=="-w" ( if not "%switch%"=="-h" ( echo Error: Invalid image width or height switch. Use -w or -h, with target image size in dp appended. goto :error )) echo %pixels%| findstr /r /c:"^[1-9][0-9]*$" >nul if errorlevel 1 ( echo Error: Invalid numeric image size. Image size must be a positive integer. goto :error ) if "%3"=="" ( echo Error: Not enough arguments. goto :error ) if not "%4"=="" ( echo Error: Too many arguments. goto :error ) call :export %1 %2 %3 mdpi call :export %1 %2 %3 hdpi call :export %1 %2 %3 xhdpi call :export %1 %2 %3 xxhdpi call :export %1 %2 %3 xxxhdpi exit /b :export rem parameters: <width/height> <input-file> <output-file> <density> set temp=%1 set switch=%temp:~0,2% set pixels=%temp:~2% if %4==mdpi set /a size=%pixels% if %4==hdpi set /a size=%pixels%*3/2 if %4==xhdpi set /a size=%pixels%*2 if %4==xxhdpi set /a size=%pixels%*3 if %4==xxxhdpi set /a size=%pixels%*4 echo %size% pixels ../res/drawable-%4/%3 "C:\Program Files\Inkscape\inkscape.exe" %switch%%size% --export-background-opacity=0 --export-png=../res/drawable-%4/%3 %2 exit /b :error echo Synopsis: svg2png -w^<width-pixels^>^|-h^<height-pixels^> ^<input-file^> ^<output-file^> echo Example: svg2png -w24 "wifi white.svg" wifi_connect_24dp.png exit /b 
0
Oct 08 '15 at 23:22
source share

svg is awesome. who wants to use svg:

right-click on drawable "new / Vector Asset", select "material icon" for the default icons and "locale SVG file" for your file on your computer’s hard drive and in the name type "resource name" for the svg file, then click "next" and "finish"

and you can use this in drawable. fillcolor should be tough.

simple example

navigation_toggle.xml

 <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path android:fillColor="#FFFFFF" android:pathData="M3,18h18v-2H3v2zm0,-5h18v-2H3v2zm0,-7v2h18V6H3z"/> </vector> 
0
Jan 14 '16 at 17:05
source share



All Articles