it-swarm.com.ru

Каковы лучшие практики использования значков SVG на Android?

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

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

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

70
user462982

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

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

26
mah

Начиная с 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

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 библиотека 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 в случае уведомлений.
15
bendaf

Поскольку ответ 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 в 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.
8
Stephan Henningsen

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

Есть несколько бесплатных инструментов конвертации.

6
Chepech

Библиотека поддержки 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

5
lordmegamax

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

3
ZeroOne

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

2
Tony O'Hagan

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

ПРОФИ

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

МИНУСЫ

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

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

2
Ciske Boekelo

Мне никогда не удавалось запустить сценарии Linux Shell в Cygwin для Windows. Итак, вот пакетный файл, который делает то, что делает bash-скрипт Nacho Coloma. Небольшое отличие состоит в том, что этот пакетный файл требует ввода и имени выходного файла, как в "svg2png -w24 input.svg output.png".

Установите папку "svg" в каталоге src/main вашего проекта и скопируйте файлы SVG и этот пакетный файл в эту папку, следуя инструкциям Стефана. Запустите пакетный файл из папки svg. Если вы используете 32-разрядную версию Windows, вам, вероятно, потребуется изменить путь к Inkscape, чтобы использовать "Program Files (x86)".

@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:

щелкните правой кнопкой мыши на нарисованном "новом/векторном активе", выберите "значок материала" для значков по умолчанию и "файл SVG-файла" для вашего файла на жестком диске вашего компьютера и в "имени ресурса" введите имя для файла SVG, затем нажмите кнопку "Далее" и "закончить"

и вы можете использовать это в Drawable. Цвет заливки должен быть жестким кодом.

простой пример

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
mehrdad khosravi