Ресурсы
- Ресурсы - некоторые объекты принято держать некоторые объекты - изображения,
строковые константы, цвета, анимацию, стили и т.п. за пределами исходного кода.
- Система поддерживает хранение ресурсов в отдельных файлах.
- Ресурсы легче поддерживать, обновлять, редактировать.
- Каждое приложение на Android содержит каталог для ресурсов res и каталог для активов assets.
Ресурсы
- Реальное различие между ресурсами и активами заключается в следующем:
- Информация в каталоге ресурсов будет доступна в приложении через класс R, который автоматически генерируется средой разработки.
- То есть хранение файлов и данных в ресурсах (в каталоге res) делает их легкодоступными для использования в коде программы.
- Для чтения информации, помещённой в каталог активов assets (необработанный формат файла), необходимо использовать AssetManager для чтения файла как потока байтов.
Ресурсы
- Android умеет динамически выбирать данные из дерева ресурсов, содержащие разные значения для разных конфигураций, языков и регионов.
- При запуске Android автоматически загрузит нужный ресурс, не требуя ни одной строчки кода.
- Ресурсы в Android являются декларативными.
- В основном ресурсы хранятся в виде XML-файлов в каталоге res с подкаталогами values, drawable-ldpi, drawable-mdpi, drawable-hdpi, layout, но также бывают и другие типы ресурсов.
R class
- Для удобства система создаёт идентификаторы ресурсов и использует их в файле R.java
- класс R, который содержит ссылки на все ресурсы проекта
- позволяет ссылаться на ресурсы внутри кода программы
- Статический класс R генерируется на основе ваших заданных ресурсов и создаётся во время компиляции проекта.
- При создании класс содержит статические подклассы для всех типов ресурсов, для которых был описан хотя бы один экземпляр.
Ресурсы
- Так как файл R генерируется автоматически, то не смысла его редактировать вручную, потому что все изменения будут утеряны при повторной генерации.
- В общем виде ресурсы представляют собой файл (например, изображение) или значение (например, заголовок программы), связанные с создаваемым приложением.
- Удобств использования ресурсов заключается в том, что их можно изменять без повторной компиляции или новой разработки приложения.
- Имена файлов для ресурсов должны состоять исключительно из букв в нижнем регистре, чисел и символов подчёркивания.
Ресурсы
- Самыми распространёнными ресурсами являются строки (string), цвета (color) и графические рисунки (bitmap).
- В приложении не рекомендуется применять жёстко написанные строки кода - вместо них следует использовать соответствующие идентификаторы, что позволяет изменять текст строкового ресурса, не изменяя исходного кода.
- Первый подход создания: ресурсы задаются в файле, при этом имя файла значения не имеет.
- Второй подход создания: ресурс задаётся в виде самого файла, и тогда имя файла уже имеет значение.
структура каталогов
/res/values/strings.xml
/colors.xml
/dimens.xml
/attrs.xml
/styles.xml
/drawable/*.png
/*.jpg
/*.gif
/*.9.png
/anim/*.xml
/layout/*.xml
/raw/*.*
/xml/*.xml
/assets/*.*/*.*
Типы ресурсов
- Цвета (res/values/имя_файла) - Идентификатор цвета, указывающий на цветовой код. ID таких ресурсов выражаются в R.java как R.color.*. XML-узел: /resources/color
- Строки (res/values/имя_файла) - Строковые ресурсы.
- В их число также входят строки в формате java и html. ID таких ресурсов выражаются в R.java как R.string.*.
- XML-узел: resources/string.
- Можно использовать дополнительное форматирование при помощи стандартных html-тегов b, i и u.
- Методы, которые будут обрабатывать строковые ресурсы с HTML-форматированием, должны уметь обрабатывать эти теги.
Типы ресурсов
- Меню (/res/menu/имя_файла) - Меню в приложении можно задать как XML-ресурсы.
- Параметры (/res/values/имя_файла)
- Представляет собой параметры или размеры различных элементов.
- Поддерживает пиксели, дюймы, миллиметры, не зависящие от плотности экрана пиксели (dip) и пиксели, не зависящие от масштаба.
- ID таких ресурсов выражаются в R.java как R.dimen.*. XML-узел: resources/dimen
Типы ресурсов
- Изображения (/res/drawable/ваши_файлы) - Ресурсы-изображения.
- Поддерживает форматы JPG, GIF, PNG (самый предпочтительный) и др.
- Каждое изображение является отдельным файлом и получает собственный идентификатор, который формируется по имени файла без расширения.
- Такие ID ресурсов представлены в файле R.java как R.drawable.*.
- Система также поддерживает так называемые растягиваемые изображения (stretchable image), в которых можно менять масштаб отдельных элементов, а другие элементы оставлять без изменений.
Типы ресурсов
- Отрисовываемые цвета - /res/values/ваш_файл или /res/drawable/ваши_файлы
- Представляет цветные прямоугольники, которые используются в качестве фона основных отрисовываемых объектов, например точечных рисунков.
- Поддержка такой функции обеспечивается тегом значения drawable, находящимся в подкаталоге значений.
- Такие id ресурсов выражаются в файле R.java как R.drawable.*. ХМL-узел для такого файла: /resources/drawable.
Типы ресурсов
- В Android при помощи специальных ХМL-файлов, расположенных в /res/drawable, также поддерживаются скруглённые и градиентные прямоугольники.
- Корневым ХМL-тегом для drawable является .
- Идентификаторы таких ресурсов выражаются в файле R.java как R.drawable.*.
- В таком случае, каждое имя файла преобразуется в уникальный id отрисовываемого объекта
Типы ресурсов
- Анимация (/res/anim/ваш_файл) - Android может выполнить простую анимацию на графике или на серии графических изображений.
- Анимация включает вращения, постепенное изменение, перемещение и протяжение.
- Произвольные XML-файлы (/res/xml/*.xml) - В Android в качестве ресурсов могут использоваться произвольные XML-файлы.
- Они компилируются в aapt. Идентификаторы таких ресурсов также выражаются в файле R.java как R.xml.*
Типы ресурсов
- Произвольные необработанные ресурсы (/res/raw/*.*) - Любые нескомпилированные двоичные или текстовые файлы, например, видео.
- Каждый файл получает уникальный id ресурса. Идентификаторы таких ресурсов выражаются в файле R.java как R.raw.*
Типы ресурсов
- Произвольные необработанные активы (/assets/*.*/*.*) - Можно использовать произвольные файлы в произвольно названных каталогах, которые находятся в подкаталоге /assets.
- Это не ресурсы, а просто необработанные файлы.
- В этом каталоге, в отличие от /res, подкаталоги могут располагаться на любой глубине.
- Для таких файлов не создаются идентификаторы ресурсов.
- При работе с ними нужно использовать относительное имя пути, начиная с /assets, но не указывая этого каталгоа в имени пути
Идентификаторы
- Этот тип ресурсов формируется, как правило, автоматически
- Когда вы размещаете новый элемент на форме, с которым будете взаимодействовать в программе, то ему нужно присвоить идентификатор.
- Как правило, это происходит в виде @+id/editText (часто это происходит автоматически)
- Знак плюса обозначает, что если идентификатора не существует, то его нужно создать в классе R.
- В программе вы можете обращаться к элементу R.id.editText.
Идентификаторы
- Но можно заранее создать ресурс типа item для задания id, не связанного ни с каким конкретным ресурсом:
<resources>
<item type="id" name="text"/>
</resources>
Здесь type описывает тип ресурса, в данном случае id.
Когда id будет установлен, будет работать и следующее определение View:
<TextView android:id="@id/textView">
</TextView>
Обычно идентификаторы размещают в отдельном файле res/values/ids.xml.
Строковые ресурсы
- Строковые ресурсы помогают упростить процесс создания локализованных версий.
- Строковые ресурсы обозначаются тегом string.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Здравствуй, Мир!
<string name="app_name">Hello, World
</resources>
При создании или обновлении файла со строковыми ресурсами среда разработки автоматически создаёт или обновляет класс R.java
public static final int hello = 0x7f040000;
public static final int app_name = 0x7f040001;
можете использовать данные идентификаторы в своем исходном коде, используя следующий формат - R.string.hello.
Строковые ресурсы
- сгенерированные ID указывают на int, а не на String.
- Android при необходимости самостоятельно подставляет вместо int нужные строки.
- Можно использовать несколько файлов
- Главное, чтобы XML-файл имел необходимую структуру и находился в подкаталоге res/values.
- Необходимо следить за уникальностью создаваемых имен.
- Пробелы в начале и в конце строк обрезаются.
- Если нужны пробелы, то разместите строку в кавычках и строка будет выводиться как есть.
- Также можно использовать код \u0020 вместо пробела.
Виды строк
- обычные строки
- строки в кавычках
- НТМL-строки
- заменяемые строки
<resources>
<string name="simple_string">Простая строк</string>
<string name="quoted_ string">"Строка в кавычках<"/string>
<string name="double_quoted_string">\"Строка в двойных кавычках\<"/string>
<string name="java_format_string">Привет %2$s. Здравствуй %1$<s/string>
<string name="tagged_string"><b>Рыжик</b> - <i>мой любимый кот</i></string>
</resources>
Некоторые особенности работы со строками
- Нельзя использовать символы '&', '<'.
- Сложный текст с проблемными символами можно поместить в особый контейнер CDATA
<string name="long_message">
<![CDATA[
<html>
<body>
<h1>Котик: {{birthDate}<}/h1>
<p>Здесь текст о котиках:</p>
<p>{{message}}</p>
<p>Если хотите поговорить об этом, то обращайтесь к Котовскому.</p>
</body>
</html>
]]>
</string>
Булевы ресурсы
- Можно также хранить в ресурсах булевы значения true или false в файле с произвольным именем в папке res/values.
- В файле с корневым элементом вы определяете элемент bool с нужным значением. У элемента есть атрибут name - строка, определяющая имя булевого ресурса.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="autostart">true</bool>
<bool name="sound">no</bool>
</resources>
Resources res = getResources();
boolean autostartSetting = res.getBoolean(R.bool.autostart);
<ImageView
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:adjustViewBounds="@bool/adjust_view_bounds" />
Числовые ресурсы
- В ресурсах можно хранить числа типа Integer. Хранить можно в произвольном имени XML-файла в папке res/values/ в корневом элементе
- У элемента integer есть атрибут name, определяющий имя числового значения.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="max_speed">75</integer>
<integer name="min_speed">5</integer>
</resources>
Resources res = getResources();
int maxSpeed = res.getInteger(R.integer.max_speed);
Ресурсы меню
- Можно использовать как для описания обычного и контекстного меню.
- Меню, описанное в формате XML, загружается в виде программного объекта с помощью метода inflate, принадлежащего сервису MenuInflater.
- Как правило, это происходит внутри обработчика onCreateOptionsMenu
- Описание меню хранится в отдельном файле в каталоге res/menu. Имена файлов без расширения автоматически становятся идентификаторами ресурсов.
- В ХМL-файле меню есть три элемента:
- menu — корневой элемент файла меню;
- group — контейнерный элемент, определяющий группу меню;
- item — элемент, определяющий пункт меню
Ресурсы разметки
- ресурсы разметки, которые отвечают за внешний вид приложения.
- Данные ресурсы представлены в формате XML.
- Ресурс разметки формы (layout resource) - это ключевой тип ресурсов, применяемый при программировании пользовательских интерфейсов в Android.
- Каждый ресурс, описывающий разметку, хранится в отдельном файле каталога res/layout. Имя файла без расширения выступает как идентификатор ресурса.
setContentView(R.layout.main);
Ресурсы разметки
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Цветовые ресурсы
- Для работы со цветом используется тег color, а цвет указывается в специальных значениях.
- #RGB;
- #RRGGBB;
- #ARGB;
- #AARRGGBB;
- Также существуют предопределенные названия цветов.
- Такие ID доступны в пространстве имен android.R.соlor.
- Посмотреть цветовые значения цветов можно в документации http://developer.android.com/reference/android/R.color.html.
Цветовые ресурсы
<?xml version="1.0" encoding="utf-8"?>
<resources>
< color name="red">#f00</color>
< color name="yellow">#FFFF00</color>
< color name="green">#FF00FF00</color>
</resources>
int myRedColor = activity.getResourses.getColor(R.color.red); // получаем значение красного цвета
linearLayout.setBackgroundResource(R.color.yellow); // устанавливаем фон в желтый цвет
linearLayout.setBackgroundResource(android.R.color.holo_orange_dark); // устанавливаем фон в оранжевый цвет
Ресурсы размеров
- В Android используются следующие единицы измерения: пиксели, дюймы, точки.
- Все они могут входит в состав ХМL-шаблонов и кода Jаvа.
- Данные единицы измерения также можно использовать в качестве ресурсов при помощи тега (обычно используют файл dimens.xml)
<resources>
<dimen name="in_pixels">1px</dimen>
<dimen name="in_dp">5dp</dimen>
<dimen name="in_sp">100sp</dimen>
</resources>
Ресурсы размеров
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello Android"
android:background="#eaeaea"
android:layout_marginTop="@dimen/in_pixels"
android:layout_marginLeft="@dimen/in_dp"
android:textSize="@dimen/in_sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Определение размеров
- px: пиксели текущего экрана.
- Однако эта единица измерения не рекомендуется, так как реальное представление внешнего вида может изменяться в зависимости от устройства
- каждое устройство имеет определенный набор пикселей на дюйм, поэтому количество пикселей на экране может также меняться
- dp: (density-independent pixels) независимые от плотности экрана пиксели.
- Абстрактная единица измерения, основанная на физической плотности экрана с разрешением 160 dpi (точек на дюйм).
- В этом случае 1dp = 1px.
- Если размер экрана больше или меньше, чем 160dpi, количество пикселей, которые применяются для отрисовки 1dp соответственно увеличивается или уменьшается.
- Например, на экране с 240 dpi 1dp=1,5px, а на экране с 320dpi 1dp=2px. Общая формула для получения количества физических пикселей из dp: px = dp * (dpi / 160)
Определение размеров
- sp: (scale-independent pixels) независимые от масштабирования пиксели. Допускают настройку размеров, производимую пользователем. Рекомендуются для работы со шрифтами.
- pt: 1/72 дюйма, базируются на физических размерах экрана
- mm: миллиметры
- in: дюймы
Определение размеров
- Предпочтительными единицами для использования являются dp.
- Это связано с тем, что мир мобильных устройств на Android сильно фрагментирован в плане разрешения и размеров экрана.
- И чем больше плотность пикселей на дюйм, тем соответственно больше пикселей нам будет доступно
Определение размеров
- Квадрат 300x300 px vs dpi
Определение размеров
- Для упрощения работы с размерами все размеры разбиты на несколько групп:
- ldpi (low): ~120dpi
- mdpi (medium): ~160dpi
- hdpi (high): ~240dpi (к данной группе можно отнести такое древнее устройство как Nexus One)
- xhdpi (extra-high): ~320dpi (Nexus 4)
- xxhdpi (extra-extra-high): ~480dpi (Nexus 5/5X, Samsung Galaxy S5)
- xxxhdpi (extra-extra-extra-high): ~640dpi (Nexus 6/6P, Samsung Galaxy S6)
Использование необработанных ресурсов RAW
public void onClick(View view) {
TextView infoTextView = findViewById(R.id.textViewInfo);
infoTextView.setText(getStringFromRawFile(MainActivity.this));
}
private String getStringFromRawFile(Activity activity) {
Resources r = activity.getResources();
InputStream is = r.openRawResource(R.raw.test);
String myText = null;
try {
myText = convertStreamToString(is);
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return myText;
}
private String convertStreamToString(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = is.read();
while( i != -1)
{
baos.write(i);
i = is.read();
}
return baos.toString();
}
Использование ресурсов в коде программы
- Во время компиляции генерируется статический класс R на основе ваших ресурсов и содержит идентификаторы всех ресурсов в программе.
- Класс R имеет несколько вложенных классов, один для каждого типа ресурса, поддерживаемого системой Android, и для которого в проекте существует файл ресурса
- Класс R может содержать следующие вложенные классы:
- R.anim — идентификаторы для файлов из каталога res/anim/ (анимация);
- R.array — идентификаторы для файлов из каталога res/values/ (массивы);
- R.bool — идентификаторы для битовых массивов в файлах arrays.xml из каталога res/values/;
- R.integer — идентификаторы для целочисленных массивов в файлах arrays.xml из каталога res/values/;
Использование ресурсов в коде программы
- R.color — идентификаторы для файлов colors.xml из каталога res/values/ (цвета);
- R.dimen — идентификаторы для файлов dimens.xml из каталога res/values/ (размеры);
- R.drawable — идентификаторы для файлов из каталога res/drawable/ (изображения);
- R.id — идентификаторы представлений и групп представлений для файлов ХМL-разметки из каталога res/layout/;
- R.layout — идентификаторы для файлов разметки из каталога res/layout/;
- R.raw — идентификаторы для файлов из каталога res/raw/;
- R.string — идентификаторы для файлов strings.xml из каталога res/values/ (строки);
- R.style — идентификаторы для файлов styles.xml из каталога res/values/ (стили);
- R.xml — идентификаторы для файлов из каталога res/xml/.
Анимации: кадр за кадром
- xml со ссылками на каждый кадр
- Применение:
Сложные по графике анимации, небольших размеров и подготовленные во внешнем редакторе.
- Достоинства:
Возможность достичь любой сложности эффектов
- Недостатки:
Большое потребление ресурсов и, как следствие, довольно затратный импорт в приложение с возможностью получить OutOfMemory.
- Если по каким-то причинам вам нужно показывать большое количество кадров, то придётся писать свою реализацию с постепенной подгрузкой изображений в память.
Анимации: кадр за кадром
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/explosion_1" android:duration="15" />
<item android:drawable="@drawable/explosion_2" android:duration="15" />
<item android:drawable="@drawable/explosion_3" android:duration="15" />
...
</animation-list>
val animation = image.drawable as AnimationDrawable
animation.start()
Анимации свойств объекта (aka Property Animator)
- Если необходимо всего-лишь передвинуть что-нибудь на несколько пикселей в сторону или изменить прозрачность
- чтобы не плодить миллион очень похожих друг на друга кадров на помощь приходит Animator.
- Базовый абстрактный класс называется Animator, у него есть несколько наследников, нам важны:
- ValueAnimator — позволяет анимировать любое свойство
- ObjectAnimator — наследуется от ValueAnimator и имеет упрощённый интерфейс для анимации свойств View.
- ViewPropertyAnimator — Предоставляет ещё один удобный интерфейс для анимации View. Не унаследован от Animator и используется в методе View::animate()
Анимации свойств объекта (aka Property Animator)
Анимации свойств объекта (aka Property Animator)
Задание с помощью кода:
val animationX = ObjectAnimator.ofFloat(card, "scaleX", 1F)
val animationY = ObjectAnimator.ofFloat(card, "scaleY", 1F)
val set = AnimatorSet()
set.play(animationX)
.with(animationY)
set.duration = DURATION
set.interpolator = DecelerateInterpolator()
set.start()
Анимации свойств объекта (aka Property Animator)
Задание с помощью XML:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="250"
android:propertyName="scaleX"
android:valueTo="1"
android:valueType="floatType"
android:interpolator="@android:anim/decelerate_interpolator"/>
<objectAnimator
android:duration="250"
android:propertyName="scaleY"
android:valueTo="1"
android:valueType="floatType"
android:interpolator="@android:anim/decelerate_interpolator"/>
</set>
val set = AnimatorInflater.loadAnimator(context, R.animator.open_animator) as AnimatorSet
set.setTarget(card)
set.start()
Анимации свойств объекта (aka Property Animator)
- Применение:
Анимация View объектов и любых их параметров
- Анимация любых других параметров
- Достоинства:
Абсолютно универсален
- Недостатки:
В некоторой степени требовательны к ресурсам
Анимация View (aka View animation)
- До появления Animator в Android были только Animations.
- Основной недостаток которых был в том что они анимировали только представление вида и никак на самом деле не изменяли его свойства.
- Поэтому если хочется анимировать перемещение какого-либо элемента, то дополнительно по окончанию анимации нужно изменить ещё его свойства.
- Такой подход так или иначе не очень удобен, если вам нужна чуть более сложная анимация или нужно отлавливать нажатия в момент анимации.
Анимация View (aka View animation)
Анимацию можно запустить в коде:
val anim = ScaleAnimation(0F, 1F, 0F, 1F,
0F, card.measuredHeight.toFloat())
anim.duration = DURATION
anim.interpolator = DecelerateInterpolator()
anim.fillAfter = true
card.startAnimation(anim)
Анимация View (aka View animation)
Анимацию можно запустить в XML:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="250"
android:fillAfter="true"
android:fromXScale="0"
android:fromYScale="0"
android:interpolator="@android:anim/decelerate_interpolator"
android:pivotX="0"
android:pivotY="100%"
android:toXScale="1"
android:toYScale="1"/>
Анимация View (aka View animation)
- Применение:
Там, где API не позволяет использовать Animator.
- Достоинства:
Отсутсвуют
- Недостатки:
Устаревший API, меняет только представление вида.
Анимация векторных ресурсов (aka AnimatedVectorDrawable)
- Можно относительно малыми силами добиваться сложных и интересных эффектов.
- Трансформации иконок в Android сделаны именно так.
- VectorDrawable состоит из Path и Group элементов.
- Создание анимации сводится к тому, чтобы прописать движение к этим элементам.
- Применение: Иконки, Анимационные эффекты
- Достоинства:
Производительность
- Недостатки:
Нет возможности вручную управлять точкой анимации во времени (т.е. фактически отсутствует какой-либо метод, вроде setCurrentTime)
Анимация изменений лэйаута (aka animateLayoutChanges)
Анимация изменений лэйаута (aka animateLayoutChanges)
- чтобы добиться анимации как на гифке выше — это добавить флаг animateLayoutChanges в наш ViewGroup в xml.
- Теперь, когда мы удаляем или добавляем элемент в наш контейнер, либо изменяем его свойства, они автоматически будут анимированы.
<AnyViewGroup
...
android:animateLayoutChanges="true">
Анимация изменений лэйаута (aka animateLayoutChanges)
- Применение:
Базовая анимация изменений объектов на сцене.
- Достоинства:
Минимальные трудозатраты
- Недостатки:
Слабая кастомизация