Легко переходимо на векторний формат картинок замість нарізки під різні щільності екранів у Android 4.0+. Частина 1 з 2



Зазвичай дизайн програми малюється у векторному редакторі (наприклад, Sketch), але типовим форматом зображень у додатку під Android є растровий (як правило, PNG). При розробці програми необхідно для кожного векторного зображення займатися стомлюючої роботою з виготовлення набору растрових картинок для різних щільностей екранів. Кількість таких комплектів може доходити до шести з числа можливих щільностей: ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi (щільність xxxhdpi необхідна тільки для іконки додатка). При верстці іноді доводиться поставити в розмітці явні розміри зображення, що може зажадати перемасштабирования растрової картинки, а це, в свою чергу, напевно призведе до появи артефактів. До того ж наявність декількох комплектів картинок негативно позначається на розмірі вихідного апк.

Все вирішують ці проблеми по-різному: хтось намагається підключити SVG-бібліотеку до проекту, хтось генерує нарізку з допомогою утиліти.

Як мені здається, найбільш правильним рішенням є відмова від використання растрової графіки в додатку в користь векторної. При цьому хотілося б по максимуму задіяти системні можливості. В Android 5.0 з'явився VectorDrawable – підтримка векторного формату для картинок, які розміщуються у вигляді ресурсів з розширенням xml в папці drawable. На такі картинки можна посилатися звичайним чином з XML розмітки.

Використання VectorDrawable було б відмінним рішенням, якщо б не необхідність підтримки пристроїв з Android 4.0+, яких більшість. VectorDrawable немає в support library і невідомо, коли він там з'явиться (хоча початок годиться). Але не варто засмучуватися: є чудова бібліотека BetterVectorDrawable з відкритим вихідним кодом і ліцензією Apache 2.0, яка фактично переносить VectorDrawable на Android 4.0+, надаючи той же інтерфейс, і дозволяє при необхідності використовувати системний VectorDrawable на Android 5.0+. Потрібно відзначити, що є ще пара аналогічних бібліотек, але вони не варті Вашої уваги, оскільки не дають повноцінно посилатися на vector drawable ресурси з розмітки.

На жаль, розробники Android не передбачили підтримку в VectorDrawable градієнтів, текстур, масок. Це невелика проблема, але про це слід пам'ятати при складанні дизайну програми. Якщо від цих елементів неможливо відмовитися, то можна як перш використовувати в окремих місцях растрову графіку / shape drawable, переважно перейшовши на вектор.

Отже, щоб перейти на векторний формат картинок в додатку треба:
  1. Підключити до додатка бібліотеку BetterVectorDrawable
  2. Вивантажити з векторного редактора зображення SVG форматі
  3. За допомогою конвертера сконвертувати їх усі відразу в XML-формат vector drawable
  4. Покласти отримані файли в директорію програми res/drawable
  5. Використовувати векторні зображення в розмітці і в коді як звичайні ресурси
  6. Profit
Бібліотека BetterVectorDrawable
Підключаємо бібліотеку
Щоб підключити бібліотеку до додатка досить додати один рядок в секції
dependencies
file build.gradle, розташованому в директорії модуля додатка:

dependencies {
...
compile 'com.bettervectordrawable:lib:0.4+'
}

Бібліотека поширюється через репозиторій JCenter, який використовується за замовчуванням в нових проектах Android Studio.

Якщо Ви створювали проект давно, то, можливо, у Вас використовується репозиторій Maven Central. Щоб це перевірити, треба в файлах build.gradle пошукати рядки

mavenCentral()

і додай поруч з нею

jcenter()

Включаємо перехоплення ресурсів
Бібліотеці необхідно передати список ідентифікаторів векторних ресурсів, щоб вона розуміла, які з них є vector drawable. BetterVectorDrawable буде перехоплювати звернення до них і створювати екземпляри
VectorDrawable
.
Оскільки передати список потрібно один раз, краще всього це зробити в методі
onCreate()
класу
Application
, для чого доведеться створити його спадкоємця:

package com.bettervectordrawable.demo;

import android.app.Application;
import com.bettervectordrawable.VectorDrawableCompat;

public class App extends Application {
@Override
public void onCreate() {
super.onCreate();

// виклик VectorDrawableCompat.enableResourceInterceptionFor()
}
}

І вказати цього спадкоємця в маніфесті додатки:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bettervectordrawable.demo">

<application
android:name=".App"
...

Існує три способу передати список: зручний, швидкий і ручний.

Зручний спосіб
int[] ids = VectorDrawableCompat.findAllVectorResourceIdsSlow(getResources(), R.drawable.class);
VectorDrawableCompat.enableResourceInterceptionFor(getResources(), ids);

Метод
findAllVectorResourceIdsSlow
сканує всі drawable XML-ресурси і переконується, що кожен повертається ресурс є vector drawable. Розробники радять використовувати цей метод за замовчуванням, тим не менш, це найменш продуктивний спосіб, тобто на старих пристроях час запуску програми може істотно зрости.

На Google Nexus 5 в додатку з 400 векторними ресурсами
findAllVectorResourceIdsSlow
відпрацьовує менш ніж за 150 мс.

Швидкий спосіб
int[] ids = VectorDrawableCompat.findVectorResourceIdsByConvention(getResources(), R.drawable.class, Convention.ResourceNameHasVectorSuffix);
VectorDrawableCompat.enableResourceInterceptionFor(getResources(), ids);

Метод
findVectorResourceIdsByConvention
означає, що назви всіх векторних ресурсів починаються vector_ або закінчуються на _vector. Угода щодо іменування потрібно вказати параметр
resourceNamingConvention
.

На Google Nexus 5 в додатку з 400 векторними ресурсами
findVectorResourceIdsByConvention
відпрацьовує менш ніж за 20 мс.

Ручний спосіб
VectorDrawableCompat.enableResourceInterceptionFor(getResources(),
R. drawable.your1_vector,
R. drawable.your2_vector,
R. drawable.your3_vector);

Просто передається список всіх ідентифікаторів векторних зображень. 0 мс.

Використовуємо vector drawable
У коді:

Drawable drawable = getResources().getDrawable(R. drawable.your_vector);

Або з розмітки:

<View
android:layout_width="210dp"
android:layout_height="210dp"
android:background="@drawable/your_vector" />

Як бачите, все просто.

Якщо у Вас виникли питання, то можна задати їх мені або подивитися демо-додаток. Про проблеми з бібліотекою краще повідомляти розробникам GitHub.

У наступній частині ми обговоримо конвертацію зображень SVG у vector drawable XML.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.