it-swarm.com.de

Was sind die Best Practices für die Verwendung von SVG-Symbolen unter Android?

Ich bin dabei, meine erste Android native (also nicht browserbasiert) App zu erstellen und suche nach bewährten Methoden zum Erstellen/Bereitstellen von Symbolen. Da es mehrere Geräte/Auflösungen unterstützen sollte, dachte ich, dass es am besten ist, SVG zu verwenden, um sie zu erstellen. Es gibt mindestens diese Bibliothek: http://code.google.com/p/svg-Android/ , die verspricht, Unterstützung für SVG auf Android anzubieten.

Bisher habe ich keine Ressourcen gefunden, die die Verwendung dieser oder einer anderen Bibliothek als Mittel zum Rendern von SVG-Symbolen auf dem Gerät beschreiben. Daher bin ich etwas zurückhaltend bei der Verwendung. Das Beste, was ich bisher gesehen habe, ist die Verwendung von SVG als Quellformat für das Vorrendern von png-basierten Symbolen in verschiedenen Auflösungen.

Meine Fragen lauten also: Sind SVG-Symbole eine gute Option, um sie direkt auf dem Gerät ohne einen PNG-Vorrenderschritt zu verwenden (funktioniert sie überhaupt), und wenn ja, warum scheint niemand diesen Ansatz zu verwenden?

71
user462982

Für Android älter als Lollipop, sollten Sie als beste Vorgehensweise für SVG Android) ein Tool verwenden, um Ihre SVG in PNG in der Größe (n) zu konvertieren Bestehende SVG-Unterstützung für Android ist nicht umfassend, was Sie wahrscheinlich in einer SVG-Datei finden, und selbst wenn dies der Fall wäre, ist die Unterstützung nicht in die integriert OS, so dass es definitiv nicht möglich ist, sie direkt für Symbole zu verwenden.

Beginnend mit Lollipop (API 21) siehe Was sind die Best Practices für die Verwendung von SVG-Symbolen unter Android? . Vielen Dank an @MarkWhitaker @AustynMahoney für diesen Hinweis.

26
mah

Ab Lollipop (API 21) definiert Android) die Klasse VectorDrawable , zum Definieren von Zeichen auf der Basis von Vektorgrafiken. Android Studio 1.4 fügt das "Vector Asset Studio" hinzu um die Arbeit zu erleichtern, einschließlich einer SVG-Importfunktion und eines neuen Gradle-Plugins, das PNG-Versionen von VectorDrawable-Symbolen zur Erstellungszeit für API 20 generiert und früher. Es gibt auch ein Drittanbieter-Tool zum Konvertieren von SVGs in VectorDrawables . Beachten Sie, dass Vektorzeichen zwar in XML definiert werden können, das Dateiformat jedoch nicht SVG ist und nicht alle SVG-Dateien erfolgreich konvertiert werden können. Einfache Grafiken wie Symbole sollten in Ordnung sein.

Wenn Sie weiterhin selbst PNGs generieren müssen, müssen Sie Ihre Symbole generieren mit verschiedenen Auflösungen . Zur Vereinfachung der Erstellung dieser PNGs gestalte ich Symbole als SVG und exportiere sie dann in die verschiedenen Größen mit Inkscape , das kostenlos und plattformübergreifend ist. Es enthält einige nette Funktionen zum Entwerfen von Symbolen, einschließlich der Symbolvorschau (siehe unten), und generiert schöne, gestochen scharfe PNGs.

enter image description here

42
Mark Whitaker

Dies verwenden wir, um eine SVG-Datei in mehrere Auflösungen umzuwandeln. So generieren Sie beispielsweise das Startsymbol: 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

Gute Nachrichten, Leute! Seit Android support library 23.2 können wir svg-s bis zurück zu API Level 7 verwenden !

Wenn Sie nur bis Lollipop (API 21) rückwärts kompatibel sein möchten, aktivieren Sie Mark Whitaker's answer, aber wenn Sie weiter unten gehen möchten, müssen Sie diese Zeilen zu Ihrem build.gradle hinzufügen:

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

Denken Sie auch daran, dass:

  • anstelle von Android:src müssen Sie in ImageViews das Attribut app:srcCompat verwenden.
  • sie können svg-s nicht in StateListDrawables oder anderen XML-Drawables verwenden, sondern programmgesteuert erstellen.
  • sie können nicht das Attribut Android:background oder die Funktion View.setBackgroundResource() verwenden, sondern die Funktion View.setBackground().
  • sie können svg-s bei Benachrichtigungen nicht verwenden.
15
bendaf

Da die Antwort von nacho-coloma mir geholfen hat, habe ich sein exzellentes Skript genommen und die tägliche Verwendung etwas vereinfacht.

Zuerst:

  1. Erstellen Sie ein Verzeichnis drawable-svg Neben Ihrem res -Verzeichnis.
  2. Platzieren Sie Ihre SVG-Dateien und dieses Skript in drawable-svg.
  3. Machen Sie das Skript ausführbar.
  4. Starte es. In Ubuntu können Sie einfach in Nautilus darauf doppelklicken und es in einem Terminal ausführen.

Und später, wenn Sie neue SVG-Dateien erhalten:

  1. Legen Sie neue SVG-Dateien in drawable-svg Und führen Sie das Skript erneut aus.

Standardmäßig wird es tun, was Sie wollen: Skalieren Sie jede SVG-Datei in PNG-Dateien und fügen Sie sie in ../res/drawable-mdpi, ../res/drawable-hdpi Usw. ein.

Das Skript akzeptiert zwei Parameter:

  1. Das zu skalierende SVG-Dateimuster, Standard: *.svg
  2. Das Basisverzeichnis für put ist standardmäßig ../res/ (D. H. Ihr res -Verzeichnis mit dem oben genannten Setup).

Sie können experimentieren, indem Sie eine einzelne SVG in PNGs im aktuellen Verzeichnis wie folgt skalieren:

$ ./svg2png test.svg .

Oder verarbeiten Sie einfach alle Bilder:

$ ./svg2png

Ich schätze, Sie könnten den drawable-svg Im res-Verzeichnis ablegen, aber ich habe nicht untersucht, was in der endgültigen APK verpackt wird. Außerdem haben meine SVG-Dateien - Im Namen, was Android nicht gefällt, und mein Skript kümmert sich darum, die PNG-Dateien in etwas für Android Gültiges umzubenennen.

Ich verwende ImageMagick für die Konvertierung, die etwas standardmäßiger ist als Inkscape (obwohl mir der Ansatz gefallen hat). Beide Methoden sind zu Referenzzwecken im Skript enthalten.

Hier ist das Skript:

#!/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

Eine weitere Option ist die Konvertierung Ihrer SVG-Assets in TTF-Schriftarten. Fügen Sie die Schriftart in Ihre App ein und verwenden Sie sie auf diese Weise. Dies ist der Trick für monochromatische einfache Formen.

Es gibt mehrere kostenlose Konvertierungstools.

6
Chepech

Android Support Library 23.2 Unterstützt Vektorzeichnungen und animierte Vektorzeichnungen

  1. fügen Sie Ihrer build.gradle-Datei vectorDrawables.useSupportLibrary = true hinzu.
  2. Verwenden Sie app:srcCompat="@drawable/ic_add" Anstelle von Android:src="..." Oder setImageResource() für Ihre ImageView

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

5
lordmegamax

SVG-Symbole sind keine gute Option, um sie direkt auf einem Gerät zu verwenden, wenn sie auf viele verschiedene Größen skaliert werden müssen. Deshalb sollten Sie in der Regel zunächst das Vektorformat verwenden. Ein großes Symbol wird niemals elegant verkleinert, da Computerbildschirme aus Pixeln bestehen. So können die Linien des Vektorbildes "zwischen Pixeln" ausgerichtet werden, wodurch ein unscharfer Rand entsteht. Darüber hinaus benötigen große Symbole mehr Details als kleine Symbole, für die nur sehr wenige Details erforderlich sind. Ein detailliertes Symbol sieht in sehr kleinen Dimensionen nicht gut aus, und ein einfaches Symbol sieht in sehr großen Dimensionen nicht gut aus. Ich habe kürzlich einen ausgezeichneten Artikel eines professionellen UI-Designers darüber gelesen: Über diese Vektor-Icons .

3
ZeroOne

Ich habe gerade ein Skript zum Generieren aller Plattformsymbole für PhoneGap-Apps veröffentlicht, die möglicherweise von Wert sind. Noch Code zum Generieren von Bildschirmen hinzuzufügen.

2
Tony O'Hagan

Ich habe gerade damit begonnen, Victor , eine Open-Source-Bibliothek von Trello, zu verwenden, um SVG-Dateien während der Erstellungszeit in PNG-Dateien mit den verschiedenen erforderlichen Auflösungen zu konvertieren.

PROS

  • Sie müssen nicht jedes Mal ein Skript oder Tool ausführen, um verschiedene PNG-Dateien zu erstellen, wenn Sie ein Symbol ändern oder hinzufügen. (Sie müssen Rebuild in Android Studio drücken, wenn Sie eine neue SVG-Datei hinzugefügt oder eine vorhandene umbenannt haben)
  • In Ihrer Quelle befinden sich keine PNGs, daher gibt es weniger Unordnung.

CONS

  • Der einzige Nachteil, den ich bisher gesehen habe, ist, dass Android Studio generierte Ressourcen in XML noch nicht erkennt, sodass in Ihren XML-Dateien einige rote Warnungen angezeigt werden und Sie keine haben Autovervollständigen für Ihre SVG-basierten Drawables. Es funktioniert jedoch einwandfrei, und dieses Problem sollte in einer zukünftigen Version von Android Studio behoben werden.

Wenn Sie SVG verwenden, das von http://materialdesignicons.com/ generiert wurde, müssen Sie entweder die gesamte Datei herunterladen oder von der Registerkarte "SVG-Datei" kopieren, wenn Sie "SVG anzeigen" auswählen.

2
Ciske Boekelo

Ich hatte noch nie viel Glück beim Ausführen von Linux-Shell-Skripten in Cygwin unter Windows. Hier ist also eine Batch-Datei, die das tut, was Nacho Colomas Bash-Skript tut. Ein kleiner Unterschied besteht darin, dass für diese Batchdatei sowohl ein Eingabe- als auch ein Ausgabedateiname erforderlich sind, wie in "svg2png -w24 input.svg output.png".

Richten Sie einen "svg" -Ordner im src/main-Verzeichnis Ihres Projekts ein und kopieren Sie Ihre SVG-Dateien und diese Batch-Datei gemäß Stephans Anweisungen in diesen Ordner. Führen Sie die Batchdatei aus dem Ordner "svg" aus. Wenn Sie unter 32-Bit-Windows arbeiten, müssen Sie wahrscheinlich den Pfad zu Inkscape ändern, um "Programme (x86)" zu verwenden.

@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 ist super. Wer möchte Svg verwenden:

klicken Sie mit der rechten Maustaste auf "Neu/Vector Asset" und wählen Sie "Materialsymbol" für Standardsymbole und "SVG-Datei für Gebietsschema" für Ihre Datei auf Ihrer Computerfestplatte und geben Sie unter "Ressourcenname" den Namen für die SVG-Datei ein und klicken Sie dann auf "Weiter" und beende"

und Sie können das in drawable verwenden. Füllfarbe muss fester Code sein.

einfaches Beispiel

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