web-dev-qa-db-ja.com

AndroidでSVGアイコンを使用するためのベストプラクティスは何ですか?

私は最初のAndroidnative(ブラウザベースではない)アプリを作成しようとしています。アイコンの作成/プロビジョニング。複数のデバイス/解像度をサポートする必要があるため、SVGを使用してそれらを作成するのが最善であると考えました。少なくともこのlibがあります。 http://code.google.com/p/svg- Android / は、AndroidでSVGのサポートを提供することを約束します。

これまでのところ、デバイス上でSVGアイコンをレンダリングする手段として、このライブラリまたは別のライブラリの使用法を説明するリソースを見つけていないので、使用することに少し消極的です。これまで見てきた中で最高ののは、SVGをさまざまな解像度でpngベースのアイコンを事前レンダリングするためのソース形式として使用することです。

だから私の質問は次のとおりです:SVGアイコンはPNG事前レンダリングステップなしでデバイス上で直接使用するのに適したオプションですか(まったく機能しますか?)、なぜこのアプローチを使用していないのですか?

71
user462982

Android Lollipopより古い場合、AndroidでのSVGのベストプラクティスは、SVGをサイズでPNGに変換するツールを使用することです)興味がある。Androidの既存のSVGサポートは、SVGファイルで見つかる可能性のあるものを包括的ではなく、サポートされていても、サポートは組み込まれていませんOSなので、アイコンに直接使用することは間違いありません。

Lollipop(API 21)以降 AndroidでSVGアイコンを使用するためのベストプラクティスは何ですか? を参照してください。これを指摘してくれた@MarkWhitaker @AustynMahoneyに感謝します。

26
mah

Lollipop(API 21)以降、Androidは、定義のために VectorDrawable クラスを定義します Android Studio 1.4は "Vector Asset Studio"を追加します SVGインポート機能と、ビルド時にVectorDrawableアイコンのPNGバージョンを生成する新しいGradleプラグインを含む、それらを操作しやすくします。 API 20以前のバージョンもあります。 SVGをVectorDrawablesに変換するためのサードパーティ製ツール もあります。ベクトルドロウアブルはXMLで定義できますが、ファイル形式はSVGではなく、すべてのSVGファイルは正常に変換できます。アイコンのようなシンプルなグラフィックスは正常に機能するはずです。

それでも自分でPNGを生成する必要がある場合は、アイコンを生成する必要があります さまざまな解像度で 。これらのPNGを簡単に生成するために、アイコンをSVGとして設計し、 Inkscape を使用してさまざまなサイズにエクスポートします。これは無料でクロスプラットフォームです。アイコンプレビュービュー(以下を参照)など、アイコンを設計するための素晴らしい機能がいくつかあり、すてきな鮮明なPNGを生成します。

enter image description here

42
Mark Whitaker

これは、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
31
Nacho Coloma

皆さん、朗報です! Android support library 23.2 なので、APIレベル7に戻るまでsvg-sを使用できます!

Lollipop(API 21)までのみ後方互換性を維持したい場合は、 Mark Whitaker's answerをチェックしてください。

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

また、次のことに注意してください。

  • _Android:src_の代わりに、ImageViewsで_app:srcCompat_属性を使用する必要があります。
  • stateListDrawablesまたはその他のxmlドロアブルでsvg-sを使用することはできません。代わりにプログラムで作成してください。
  • _Android:background_属性またはView.setBackgroundResource()関数を使用することはできません。代わりにView.setBackground()を使用してください。
  • 通知の場合はsvg-sを使用できません。
15
bendaf

nacho-colomaの答えが私を助けてくれたので、私は彼の優れたスクリプトを取り入れ、日常的に少し使いやすくしました。

最初:

  1. resディレクトリの横にディレクトリdrawable-svgを作成します。
  2. Svgファイルとこのスクリプトをdrawable-svgに配置します。
  3. スクリプトを実行可能にします。
  4. それを実行します。 Ubuntuでは、単純にNautilusでダブルクリックして、ターミナルで実行できます。

その後、新しいsvgファイルを取得したとき:

  1. 新しいsvgファイルをdrawable-svgに配置して、スクリプトを再度実行します。

デフォルトでは、必要な処理を実行します。すべてのsvgファイルをpngファイルにスケーリングし、../res/drawable-mdpi../res/drawable-hdpiなどに配置します。

スクリプトは2つのパラメーターを取ります。

  1. スケーリングするsvgファイルパターン、デフォルト:*.svg
  2. Putのベースディレクトリ、デフォルトは../res/(つまり、上記の設定のresディレクトリ)。

次のように、現在のディレクトリで単一のsvgをpngにスケーリングすることで実験できます。

$ ./svg2png test.svg .

または、すべての画像を単純に処理します。

$ ./svg2png

Resディレクトリ内にdrawable-svgを配置できると思いますが、最終的な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.
8

もう1つのオプションは、SVGアセットをTTFフォントタイプに変換することです。アプリにフォントを含めて、そのように使用します。これは、単色の単純な形状のトリックです。

無料の変換ツールがいくつかあります。

6
Chepech

Androidサポートライブラリ23.2サポートベクタードロアブルとアニメーションベクタードロアブル

  1. _vectorDrawables.useSupportLibrary = true_をbuild.gradleファイルに追加します。
  2. ImageViewに_app:srcCompat="@drawable/ic_add"_またはsetImageResource()の代わりに_Android:src="..."_を使用します

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

5
lordmegamax

SVGアイコンは、さまざまなサイズに拡大縮小する必要がある場合、デバイスで直接使用するのに適したオプションではありません。通常、最初にベクター形式を使用する理由です。コンピューターのディスプレイはピクセルで構成されているため、大きなアイコンが適切に縮小されることはありません。そのため、ベクトル画像の線が「ピクセル間」で整列し、ぼやけた境界線が作成される場合があります。さらに、大きなアイコンは詳細がほとんど必要ない小さなアイコンよりも詳細が必要です。詳細なアイコンは非常に小さいサイズでは見栄えが悪く、単純なアイコンは非常に大きなサイズに拡大縮小すると見栄えがよくありません。私は最近、プロのUIデザイナーによるこれに関する素晴らしい記事を読みました: それらのベクトルアイコンについて

3
ZeroOne

価値のあるPhoneGapアプリのすべてのプラットフォームアイコンを生成するスクリプトを投稿しました。まだ画面を生成するためのコードを追加します。

2
Tony O'Hagan

Trelloのオープンソースライブラリである Victor を使用して、ビルド時にSVGファイルをさまざまな解像度のPNGファイルに変換し始めました。

長所

  • アイコンを変更または追加するたびにスクリプトまたはツールを実行してさまざまなPNGファイルを作成する必要はありません。 (新しいsvgファイルを追加した場合、または既存のsvgファイルの名前を変更した場合、Android StudioでRebuildを押す必要があります)
  • ソースにPNGがないため、混乱が少なくなります。

短所

  • これまで見てきた唯一の欠点は、Android StudioはXMLで生成されたリソースをまだ認識していないため、XMLファイルに赤い警告が表示され、 SVGベースのドロアブルのオートコンプリート。ただし、うまくビルドされます。この問題は、Android Studio。

http://materialdesignicons.com/ によって生成されたSVGを使用する場合、「SVGの表示」を選択する際には、必ずファイル全体をダウンロードするか、「SVGファイル」タブからコピーしてください。

2
Ciske Boekelo

Windows上のCygwinでLinux Shellスクリプトを実行することは、これほど幸運なことではありません。 Nacho Colomaのbashスクリプトが行うことを行うバッチファイルは次のとおりです。 1つの小さな違いは、このバッチファイルには、「svg2png -w24 input.svg output.png」のように、入力ファイル名と出力ファイル名の両方が必要なことです。

ステファンの指示に従って、プロジェクトのsrc/mainディレクトリに「svg」フォルダを設定し、SVGファイルとこのバッチファイルをそのフォルダにコピーします。 svgフォルダーからバッチファイルを実行します。 32ビットWindowsを使用している場合は、「Program Files(x86)」を使用するようにInkscapeへのパスを変更する必要があります。

@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
Linda X

svgは素晴らしいです。 svgを使用したい人:

描画可能な「new/Vector Asset」を右クリックし、デフォルトのアイコンに「素材アイコン」を選択し、コンピューターのハードドライブにあるファイルに「素材SVGファイル」を選択し、「リソース名」でsvgファイルに名前を入力し、「次へ」ボタンをクリックしますそして「終了」

それをドロアブルで使用できます。 fillcolorはハードコードでなければなりません。

簡単な例

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