Каковы лучшие практики использования значков SVG на Android? - PullRequest
70 голосов
/ 10 марта 2012

Я собираюсь создать свое первое приложение для Android native (поэтому не основанное на браузере) и ищу некоторые полезные рекомендации по созданию и обеспечению значков.Поскольку он должен поддерживать несколько устройств / разрешений, я подумал, что для их создания лучше всего использовать SVG.По крайней мере, есть эта библиотека: http://code.google.com/p/svg-android/, которая обещает предложить поддержку SVG на Android.

До сих пор я не нашел ресурсов, описывающих использование этой или другой библиотеки в качестве средства визуализации.Иконки SVG на устройстве, поэтому я немного неохотно им пользуюсь.Лучшее, что я видел до сих пор, - это использование SVG в качестве исходного формата для предварительного рендеринга значков на основе png в разных разрешениях.

Поэтому мои вопросы таковы: являются ли значки SVG хорошим вариантом для использования непосредственно на устройстве безpng этап предварительного рендеринга (работает ли он вообще), и если, почему никто не использует этот подход?

Ответы [ 12 ]

42 голосов
/ 24 марта 2015

Начиная с Lollipop (API 21) и далее, Android определяет класс VectorDrawable для определения рисованных объектов на основе векторной графики. Android Studio 1.4 добавляет «Vector Asset Studio» , чтобы с ними было проще работать, включая функцию импорта SVG и новый плагин Gradle, который генерирует PNG-версии значков VectorDrawable во время сборки для API 20 и более ранних версий.Существует также сторонний инструмент для преобразования SVG в VectorDrawables .Имейте в виду, что, хотя векторные рисунки могут быть определены в XML, формат файла не является SVG, и не все файлы SVG могут быть успешно преобразованы.Простая графика, например пиктограммы, должна работать хорошо.

Если вам все еще нужно создавать PNG самостоятельно, вам нужно сгенерировать иконки с различными разрешениями .Для простоты создания этих PNG я разрабатываю значки в формате SVG, а затем экспортирую в различные размеры, используя Inkscape , который является бесплатным и кроссплатформенным.У него есть несколько полезных функций для создания иконок, включая представление предварительного просмотра иконок (см. Ниже), и он генерирует красивые четкие изображения в формате PNG.

enter image description here

31 голосов
/ 11 апреля 2014

Это то, что мы используем для преобразования файла 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
26 голосов
/ 10 марта 2012

Для Android старше Lollipop лучшим вариантом для SVG на Android будет использование инструмента для конвертации SVG в PNG нужного вам размера. Существующая поддержка SVG для Android не является исчерпывающей.того, что вы, вероятно, найдете в SVG-файле, и даже если бы это было так, поддержка не встроена в ОС, поэтому использование их непосредственно для иконок определенно отсутствует.

Начиная с Lollipop (API 21)см. Каковы лучшие практики использования значков SVG на Android? .Спасибо @MarkWhitaker @AustynMahoney за указание на это.

15 голосов
/ 10 августа 2016

Хорошие новости всем! Поскольку поддержка Android библиотека 23,2 , мы можем использовать svg-s, пока не вернемся к API-уровню 7 !

Если вы хотите быть совместимым в обратном направлении только до Lollipop (API 21), отметьте Отметьте ответ Уитакера, но если вы хотите пойти ниже, вам нужно добавить эти строки в свой build.gradle:

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

Также имейте в виду, что:

  • вместо android:src необходимо использовать атрибут app:srcCompat в ImageViews.
  • вы не можете использовать svg-s в StateListDrawables или других XML-чертежах, создавайте их программно.
  • вы не можете использовать атрибут android:background или View.setBackgroundResource(), используйте вместо него View.setBackground().
  • вы не можете использовать svg-s в случае уведомлений.
8 голосов
/ 08 марта 2015

Поскольку ответ nacho-coloma помог мне, я взял его превосходный сценарий и немного облегчил его использование на ежедневной основе.

Первое:

  1. Создайте каталог drawable-svg рядом с вашим каталогом res.
  2. Поместите ваши SVG-файлы и этот скрипт в drawable-svg.
  3. Сделайте скрипт исполняемым.
  4. Запустите его.В Ubuntu вы можете просто дважды щелкнуть по нему в Nautilus и запустить в терминале.

И позже, когда вы получите новые svg-файлы:

Поместите новые svg-файлы в drawable-svg и снова запустите скрипт.

По умолчанию он будет делать то, что вам нужно: масштабировать каждый svg-файл в png-файлы и помещать их в ../res/drawable-mdpi,../res/drawable-hdpi и т. Д.

Сценарий принимает два параметра:

  1. Шаблон файла SVG для масштабирования, по умолчанию: *.svg
  2. Базовый каталог для пут,по умолчанию ../res/ (т. е. ваш каталог res с вышеупомянутой настройкой).

Вы можете поэкспериментировать, масштабируя один svg в pngs в текущем каталоге следующим образом:

$ ./svg2png test.svg .

Или просто обработать все изображения:

$ ./svg2png

Полагаю, вы могли бы поместить 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.
6 голосов
/ 12 ноября 2014

Другой вариант - конвертировать SVG-ресурсы в тип шрифта TTF.Включите шрифт в ваше приложение и используйте его таким образом.Это делает трюк для монохроматических простых форм.

Есть несколько бесплатных инструментов для конвертации.1012 *http://www.freefontconverter.com

5 голосов
/ 27 июля 2016

Библиотека поддержки Android 23.2 Поддержка векторных рисунков и анимационных векторных рисунков

  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

3 голосов
/ 22 апреля 2012

Иконки SVG не являются хорошим вариантом для непосредственного использования на устройстве, если их нужно масштабировать до разных размеров, поэтому обычно вам стоит использовать векторный формат. Большой значок никогда не будет грациозно уменьшаться, потому что компьютерные дисплеи сделаны из пикселей. Таким образом, линии векторного изображения могут быть выровнены «между пикселями», создавая размытую границу. Кроме того, большие значки требуют больше деталей, чем маленькие значки, которые требуют очень мало деталей. Детализированная иконка не очень хорошо выглядит в очень маленьких размерах, а простая иконка не очень хорошо выглядит при масштабировании очень больших размеров. Недавно я прочитал отличную статью об этом от профессионального дизайнера пользовательского интерфейса: Об этих векторных значках .

2 голосов
/ 17 июня 2015

Я только начал использовать Victor , библиотеку с открытым исходным кодом от Trello, для преобразования SVG-файлов в PNG-файлы с различными необходимыми разрешениями во время сборки.

PROS

  • Вам не нужно будет запускать сценарий или инструмент для создания различных файлов PNG каждый раз, когда вы меняете или добавляете значок.(Вам нужно нажать «Перестроить» в Android Studio, когда вы добавили новый svg-файл или переименовали существующий)
  • Нет PNG в вашем источнике, поэтому меньше беспорядка.

CONS

  • Единственный недостаток, который я до сих пор видел, это то, что Android Studio еще не распознает сгенерированные ресурсы в XML, поэтому вы получите несколько красных предупреждений в ваших XML-файлах, и вы неу вас не будет автозаполнения для ваших SVG-файлов.Тем не менее, он прекрасно работает, и эта проблема должна быть исправлена ​​в будущей версии Android Studio.

Если вы используете SVG, сгенерированный http://materialdesignicons.com/, обязательно загрузите весь файл, илископировать из вкладки «Файл SVG» при выборе «Просмотр SVG»

2 голосов
/ 28 августа 2014

Я только что опубликовал скрипт для генерации всех значков платформы для приложений PhoneGap, которые могут иметь значение.Еще добавить код для генерации экранов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...