在Android上使用SVG图标的最佳实践是什么?
我将要创建我的第一个安卓原生(因此不是基于浏览器的)应用程序,并寻找一些关于图标创建/设置的良好实践。 因为它应该支持多个设备/分辨率,所以我认为最好使用SVG来创建它们。至少有这样一个库:它承诺在Android上提供对SVG的支持 到目前为止,我还没有找到描述使用这个或另一个库作为在设备上呈现SVG图标的方法的资源,所以我有点不愿意使用它。到目前为止,我看到的最好的方法是使用SVG作为源格式,以不同的分辨率预渲染基于png的图标在Android上使用SVG图标的最佳实践是什么?,android,svg,icons,Android,Svg,Icons,我将要创建我的第一个安卓原生(因此不是基于浏览器的)应用程序,并寻找一些关于图标创建/设置的良好实践。 因为它应该支持多个设备/分辨率,所以我认为最好使用SVG来创建它们。至少有这样一个库:它承诺在Android上提供对SVG的支持 到目前为止,我还没有找到描述使用这个或另一个库作为在设备上呈现SVG图标的方法的资源,所以我有点不愿意使用它。到目前为止,我看到的最好的方法是使用SVG作为源格式,以不同的分辨率预渲染基于png的图标 因此,我的问题是:SVG图标是否是一个不需要png预渲染步骤就可
因此,我的问题是:SVG图标是否是一个不需要png预渲染步骤就可以直接在设备上使用的好选项(它是否工作),如果,为什么没有人使用这种方法?对于比棒棒糖更老的安卓系统,您在安卓系统上使用SVG的最佳实践是使用一个工具将SVG转换为大小为png的png你对我感兴趣。现有的对Android的SVG支持并不全面,即使是在SVG文件中,支持也没有内置到操作系统中,因此直接将其用于图标显然是不可能的
从棒棒糖开始(API 21)参见。感谢@MarkWhitaker@AustynMahoney指出这一点。如果SVG图标需要缩放到许多不同的大小,那么它们不是直接在设备上使用的好选项,这通常是您首先希望使用矢量格式的原因。大图标永远不会优雅地缩小,因为计算机显示器是由像素组成的。因此,矢量图像的线条可能在“像素之间”对齐,从而产生模糊的边界。此外,大图标比小图标需要更多的细节,小图标只需要很少的细节。详细的图标在非常小的尺寸下看起来不好,而简单的图标在缩放到非常大的尺寸时看起来不好。我最近读了一篇由专业UI设计师撰写的关于这方面的优秀文章:。这就是我们用来将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
我刚刚发布了一个脚本,用于为PhoneGap应用程序生成所有可能有价值的平台图标。还需要添加生成屏幕的代码
- 在
目录旁边创建目录res
drawable svg
- 将svg文件和此脚本放在
中可绘制svg
- 使脚本可执行
- 运行它。在Ubuntu中,您只需在Nautilus中双击它,并使其在终端中运行 稍后,当您获得新的svg文件时:
- 将新的svg文件放在
中,然后再次运行脚本可绘制svg
默认情况下,它将执行您想要的操作:将每个svg文件缩放为png文件,并将它们放入
- 由于nacho coloma的回答对我有所帮助,我采用了他出色的脚本,使其在日常生活中更易于使用
第一:
。/res/drawable mdpi
,。/res/drawable hdpi
等
该脚本采用两个参数:
*.svg
。/res/
(即具有上述设置的res
目录)$ ./svg2png test.svg .
或者简单地处理所有图像:
$ ./svg2png
我想您可以将可绘制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.
从棒棒糖(API 21)开始,Android定义了这个类,用于定义基于矢量图形的可绘制内容。为了使它们更易于使用,包括一个SVG导入功能和一个新的Gradle插件,该插件在API 20和更早版本的构建时生成PNG版本的矢量绘图图标。还有。请记住,尽管可以用XML定义矢量可绘制文件,但文件格式不是SVG,并且并非所有SVG文件都可以成功转换。像图标这样的简单图形应该可以正常工作
如果您仍然需要自己生成PNG,则需要生成图标。为了便于生成这些PNG,我将图标设计为SVG,然后使用它导出到各种尺寸,这是免费的,跨平台的。它有一些很好的设计图标的功能,包括图标预览视图(见下文),并生成了清晰的PNG
我刚刚开始使用Trello开发的开源库,在构建期间将SVG文件转换为各种所需分辨率的PNG文件
专业人士
- 每次更改或添加图标时,您不必运行脚本或工具来创建各种PNG文件。(添加新svg文件或重命名现有svg文件时,确实需要在Android Studio中点击“重建”)
- 您的源代码中没有PNG,因此杂乱无章
- 到目前为止,我所看到的唯一缺点是Android Studio还不能识别XML中生成的资源,因此您的XML文件中会出现一些红色警告,并且您没有基于SVG的绘图功能的自动完成功能。不过它构建得很好,这个问题应该在Android Studio的未来版本中解决
@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
<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>
// Gradle Plugin 2.0+ (if you using older version check the library announcement link)
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}