在Android上使用SVG图标的最佳做法是什么?

use*_*982 72 icons svg android

我即将创建我的第一个Android 原生(因此不是基于浏览器的)应用程序,并寻找有关图标创建/配置的一些好的做法.由于它应该支持多个设备/分辨率,我认为最好使用SVG来创建它们.至少有这个lib:http://code.google.com/p/svg-android/承诺在Android上提供对SVG的支持.

到目前为止,我还没有找到描述这个或另一个库的使用的资源作为在设备上呈现SVG图标的方法,所以我有点不愿意使用它.到目前为止,我所看到的最好的是使用SVG作为在不同分辨率下预渲染基于png的图标的源格式.

所以我的问题是:SVG图标是一个很好的选择,可以直接在设备上使用而无需png预渲染步骤(它是否可以工作),如果,为什么似乎没有人使用这种方法?

Mar*_*ker 44

从Lollipop(API 21)开始,Android定义了VectorDrawable类,用于根据矢量图形定义drawable.Android Studio 1.4添加了"Vector Asset Studio"以使其更易于使用,包括SVG导入功能和新的Gradle插件,可在构建时为API 20及更早版本生成VectorGrawable图标的PNG版本.还有一个用于将SVG转换为VectorDrawables的第三方工具.请记住,尽管可以使用XML定义矢量drawable,但文件格式不是SVG,并且不能成功转换所有SVG文件.像图标这样的简单图形应该可以.

如果您仍然需要自己生成PNG,则需要以各种分辨率生成图标.为了便于生成这些PNG,我将图标设计为SVG,然后使用免费和跨平台的Inkscape导出到各种大小.它有一些很好的设计图标功能,包括图标预览视图(见下文),它可以生成漂亮的清晰PNG.

在此输入图像描述

  • 不幸的是,SVG Import功能非常非常基础. (2认同)
  • Android团队已发布Android Studio 1.4中向量资产的向后兼容性支持.我已经更新了答案以反映这一点.http://android-developers.blogspot.com/2015/09/android-studio-14.html (2认同)

Nac*_*oma 31

这就是我们用来将SVG文件转换为多种分辨率的方法.例如,要生成启动图标: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
Run Code Online (Sandbox Code Playgroud)


mah*_*mah 27

对于比Lollipop更早的Android,你在Android上使用SVG的最佳做法是使用工具将SVG转换为你感兴趣的大小的PNG.现有的Android支持SVG并不全面. '很可能在SVG文件中找到,即使它是,但是支持不是内置在操作系统中,因此直接使用它们来获取图标肯定是不合适的.

从Lollipop(API 21)开始,请参阅在Android上使用SVG图标的最佳做法是什么?.感谢@MarkWhitaker @AustynMahoney指出这一点.

  • 这个答案现在肯定不正确.http://stackoverflow.com/a/29229005/116938 (2认同)

ben*_*daf 15

大家好消息!由于android支持库23.2我们可以使用svg-s直到回到API级别7!

如果你想向后兼容,直到Lollipop(API 21)检查Mark Whitaker的答案,但如果你想要进入下面,你需要将这些行添加到build.gradle:

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

还要记住:

  • 而不是android:src你需要app:srcCompat在ImageViews中使用该属性.
  • 你不能在StateListDrawables或其他xml drawables中使用svg-s,而是以编程方式创建它们.
  • 你不能使用android:background属性或View.setBackgroundResource()功能,View.setBackground()而是使用.
  • 在通知的情况下,您不能使用svg-s.


Ste*_*sen 8

由于nacho-coloma的回答对我有所帮助,我采用了他优秀的剧本,使其每天使用起来更容易一些.

第一:

  1. 创建目录drawable-svg旁边的res目录.
  2. 将您的svg文件和此脚本放入drawable-svg.
  3. 使脚本可执行.
  4. 运行.在Ubuntu中,您只需在Nautilus中双击它并使其在终端中运行即可.

以后当你得到新的svg文件时:

  1. 放置新的svg文件drawable-svg并再次运行该脚本.

默认情况下,它会执行您想要的操作:将每个svg文件扩展为png文件并将其放入../res/drawable-mdpi,../res/drawable-hdpi等等.

该脚本有两个参数:

  1. 要扩展的svg文件模式,默认值: *.svg
  2. put的基本目录,默认../res/(即res具有上述设置的目录).

您可以通过将单个svg缩放到当前目录中的png来进行实验,如下所示:

$ ./svg2png test.svg .
Run Code Online (Sandbox Code Playgroud)

或者只是处理所有图像:

$ ./svg2png
Run Code Online (Sandbox Code Playgroud)

我猜你可以把它drawable-svg放在res目录里面,但是我还没有看到最终APK中包含的内容.此外,我的svg文件有-他们的名字,Android不喜欢,我的脚本负责将png文件重命名为Android上的有效内容.

我正在使用ImageMagick进行转换,这比Inkscape稍微更标准(虽然我喜欢这种方法).这两种方法都包含在脚本中以供参考.

这是脚本:

#!/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.
Run Code Online (Sandbox Code Playgroud)


Che*_*ech 6

另一种选择是将SVG资产转换为TTF字体类型.在您的应用中包含该字体并以这种方式使用它.这就是单色简单形状的技巧.

有几种免费的转换工具.


lor*_*max 5

Android支持库23.2支持向量Drawables和动画矢量Drawables

  1. 添加vectorDrawables.useSupportLibrary = true到build.gradle文件中.
  2. 使用 app:srcCompat="@drawable/ic_add"而不是android:src="..."setImageResource()用于您的ImageView

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