What are best practices for using SVG icons on Android?

前端 未结 12 1332
臣服心动
臣服心动 2020-12-12 11:46

I am about to create my first Android native (so not browser based) app and looking for some good practices regarding icon creating/provisioning. Since it s

相关标签:
12条回答
  • 2020-12-12 11:59

    Another option is to convert your SVG assets into TTF font type. Include the font on your app and use it that way. This does the trick for monochromatic simple shapes.

    There are several free conversion tools.

    • http://fontastic.me
    • https://onlinefontconverter.com
    • http://www.freefontconverter.com
    0 讨论(0)
  • 2020-12-12 12:02

    I've just started using Victor, an open source library by Trello, to convert SVG files to PNG files of the various required resolutions during build time.

    PROS

    • You won't have to run a script or tool to create various PNG files every time you change or add an icon. (You do need to hit Rebuild in Android Studio when you've added a new svg file or renamed an existing one)
    • No PNG's in your source, so there's less clutter.

    CONS

    • The only downside I've seen so far is that Android Studio doesn't yet recognize generated resources in XML, so you'll get some red warnings in your XML files and you don't have autocomplete for your SVG based drawables. It builds fine though, and this issue should be fixed in a future version of Android Studio.

    If you use SVG generated by http://materialdesignicons.com/ be sure to either download the whole file, or copy from the 'SVG File'-tab when choosing 'View SVG'

    0 讨论(0)
  • 2020-12-12 12:04

    I've never had much luck running Linux shell scripts in Cygwin on Windows. So here is a batch file that does what Nacho Coloma's bash script does. One small difference, is that this batch file requires both an input and an output file name, as in "svg2png -w24 input.svg output.png".

    Set up an "svg" folder in your project's src/main directory and copy your SVG files and this batch file to that folder, per Stephan's instructions. Run the batch file from the svg folder. If you're on 32-bit Windows, then you will 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 讨论(0)
  • 2020-12-12 12:05

    Since nacho-coloma's answer helped me, I've taken his excellent script and made it slightly easier to use on a daily basis.

    First:

    1. Create directory drawable-svg next to your res directory.
    2. Place your svg files and this script in drawable-svg.
    3. Make the script executable.
    4. Run it. In Ubuntu you can simply double-click it in Nautilus and make it run in a terminal.

    And later when you get new svg files:

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

    By default it will do what you want: Scale every svg file into png files and put them into ../res/drawable-mdpi, ../res/drawable-hdpi etc.

    The script takes two parameters:

    1. The svg file pattern to scale, default: *.svg
    2. The base directory for put, default ../res/ (i.e. your res directory with the above mentioned setup).

    You can experiment by scaling a single svg into pngs in the current directory like this:

    $ ./svg2png test.svg .
    

    Or simply process all images:

    $ ./svg2png
    

    I guess you could place the drawable-svg inside the res directory, but I haven't looked into what gets wrapped up in the final APK. Also, my svg files have - in their names, which Android doesn't like, and my script takes care of renaming the png files to something valid on Android.

    I'm using ImageMagick for the conversion which is slightly more standard that Inkscape (though 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.
    
    0 讨论(0)
  • 2020-12-12 12:07

    SVG icons are not a good option to use directly on a device if they need to be scaled to many different sizes, which is usually why you'd want to use vector format in the first place. A large icon will never scale down gracefully because, well, computer displays are made out of pixels. So the lines of the vector image may get aligned "in between pixels", creating a blurry border. Moreover, large icons need more details than small icons, which need very few details. A detailed icon does not look good in very small size, and a simple icon does not look good when scaled into very large size. I recently read an excellent article on this by a professional UI designer: About those vector icons.

    0 讨论(0)
  • 2020-12-12 12:07

    I've just posted a script for generating all the platform icons for PhoneGap apps that may be of value. Yet to add code for generating screens.

    • https://github.com/tohagan/phonegap-graphics
    0 讨论(0)
提交回复
热议问题