Flutter-проект может содержать не только файлы с кодом, но и различные файлы ресурсов, которые называются ассетами (англ. assets). К самым распространённым типам ресурсов относятся статические данные, файлы конфигурации, иконки и изображения.
В этом параграфе мы разберёмся, как добавить ассеты в проект и на что обратить внимание.
Как добавить новый ресурс
Для начала нам необходимо перенести нужный файл в папку проекта. Общепринятое решение — создавать папку с именем assets на уровне папки lib и хранить все ресурсы проекта в ней. Дальше необходимо указать расположение ресурса в файле pubspec.yaml в секции flutter:.
Теперь добавим наши ассеты. Рассмотрим процесс на примере:
- изображений;
- шрифтов;
- текста;
- иконок приложения;
- стартового экрана (Launch Screen).
Изображения
Пример, как добавить изображение в файл проекта pubspec.yaml:
1flutter:
2 assets:
3 - assets/folder_name/asset_name.png ## Добавится изображение png
4 - assets/folder_name/asset_name.svg ## Добавится изображение svg
5 - assets/folder_name/ ## Добавятся все ресурсы из папки assets/folder_name
6 - my_folder/ ## Добавятся все ресурсы из папки my_folder
7 - packages/package_name/assets/folder_name/asset_name.png ## Добавится asset_name.png из пакета package_name
После добавления в проект доступ к изображению можно получить через класс AssetImage или Image.asset. Например, для показа изображения, которое находится по пути assets/folder_name/asset_name.png, нужно создать экземпляр Image.asset таким образом: Image.asset('assets/folder_name/asset_name.png').
Зависимые от pixel ratio изображения
Flutter может загружать изображения с соответствующим разрешением для текущего соотношения пикселей устройства (англ. pixel ratio).
Что такое pixel ratio
Это отношение между физическим количеством пикселей устройства и логическим количеством пикселей, с которым работает приложение.
В мобильных устройствах используется различное физическое разрешение экрана. Устройства с более высоким разрешением имеют большее количество физических пикселей на экране, что позволяет отображать изображения с более высокой чёткостью и детализацией.
При этом в разработке приложений часто используется логическое разрешение, которое измеряется в логических пикселях.
Логический пиксель — абстрактная единица измерения, используемая для создания интерфейса приложения.
Коэффициент пикселей устройства позволяет адаптировать приложение к физическому разрешению экрана устройства. Он определяет, какое количество физических пикселей будет использоваться для отображения каждого логического пикселя в приложении. Если устройство имеет коэффициент пикселей, отличный от 1.0, то для каждого логического пикселя можно использовать несколько физических пикселей для отображения более чёткого и детализированного изображения.
Например, устройство с pixel ratio 2.0 будет использовать четыре физических пикселя (два по горизонтали и два по вертикали) для отображения каждого логического пикселя.
Класс AssetImage будет автоматически сопоставлять запрошенное изображение с наиболее подходящим по соотношению пикселей устройства. Для работы автоматического сопоставления ресурсы должны быть организованы согласно определённой структуре
1icons/icon.png
2icons/Mx/icon.png
3icons/Nx/icon.png
4...и т. д.
M и N — числовые идентификаторы, соответствующие разрешению изображения. Они указывают на соотношение пикселей устройства, для которого предназначены изображения. В этом примере icon.png считается основным ресурсом, а Mx/icon.png и Nx/icon.png — вариантами. Предполагается, что основной ресурс соответствует разрешению 1.0.
Пример, как структурировать ресурсы для изображения с именем my_icon.png:
1my_icon/my_icon.png (mdpi)
2my_icon/1.5x/my_icon.png (hdpi)
3my_icon/2.0x/my_icon.png (xhdpi)
4my_icon/3.0x/my_icon.png (xxhdpi)
5my_icon/4.0x/my_icon.png (xxxhdpi)
На устройствах с коэффициентом пикселей 1.8 выбирается ресурс 2.0x/my_icon.png. Для устройства с коэффициентом пикселей 2.7 выбирается ресурс 3.0x/my_icon.png.
Если ширина и высота отображаемого изображения не указаны в виджете icon, используется номинальное разрешение для масштабирования ресурса таким образом, чтобы он занимал такое же пространство на экране, как основной ресурс, но с более высоким разрешением.
Другими словами, если my_icon.png имеет размер 72 пикселя по ширине и 72 пикселя по высоте, то 3.0x/my_icon.png должно иметь размер 216 пикселей по ширине и 216 пикселей по высоте. Однако, если ширина и высота не указаны, оба ресурса будут отображаться как 72 пикселя по ширине и 72 пикселя по высоте (в логических пикселях).
Для работы с ресурсами, зависимыми от разрешения, нужно указывать только основной ресурс или его родительский каталог. В примере ниже показаны оба варианта для my_icon:
1flutter:
2 assets:
3 - my_icon/my_icon.png # Основной ресурс
4 - my_icon/ # Родительский каталог
Использование изображений из зависимостей
Если изображение находится в импортируемом пакете, то для его использования необходимо указать поле package в AssetImage.
Например, если у пакета my_icons такая структура:
1pubspec.yaml
2icons/heart.png
3icons/1.5x/heart.png
4icons/2.0x/heart.png
5...
То загрузить изображение можно следующим образом:
1AssetImage('icons/heart.png', package: 'my_icons')
Шрифты
Для добавления шрифтов следует добавить файлы формата .ttc, .ttf или .otf, содержащие конфигурацию шрифта, и указать их в поле fonts:
1flutter:
2 fonts:
3 - family: Raleway
4 fonts:
5 - asset: assets/fonts/Raleway-Regular.ttf
6 - asset: assets/fonts/Raleway-Italic.ttf
7 style: italic
8 - family: RobotoMono
9 fonts:
10 - asset: assets/fonts/RobotoMono-Regular.ttf
11 - asset: assets/fonts/RobotoMono-Bold.ttf
12 weight: 700
Параметр family определяет семейство шрифтов. Этот параметр используется в свойстве fontFamily класса TextStyle.
asset — путь к шрифту относительно файла pubspec.yaml. В примере Raleway-Regular.ttf лежит в папке assets/fonts, которая находится на том же уровне, что и pubspec.yaml.
Один шрифт может ссылаться на несколько файлов с различными стилями шрифтов:
weightопределяет насыщенность начертания, представляет собой числовое значение в диапазоне от 100 до 900, кратное 100. Это значение соответствуетFontWeightи используется в свойствеfontWeightклассаTextStyle. К примеру, для использованияRobotoMono-Boldнужно указатьFontWeight.w700;styleопределяет контур шрифта — курсивный или обычный. Значение соответствует полюfontStyleклассаTextStyleи определяется объектомFontStyle. К примеру, для использованияRaleway-Italicнужно установитьfontStyleравнымFontStyle.italic.
Текст
Для работы с текстовыми ассетами — к примеру, файлами .txt или .json — используется класс AssetBundle.
Есть два варианта работы с AssetBundle:
- использовать статический объект rootBundle;
- использовать объект DefaultAssetBundle;
Ниже — примеры для каждого варианта.
Пример №1: используем статический объект rootBundle
Он находится в пакете flutter/services.dart.
1 import 'package:flutter/services.dart' show rootBundle;
2
3 await rootBundle.loadString('assets/config.json');
Пример №2: используем объект DefaultAssetBundle
DefaultAssetBundle — это InheritedWidget, который позволяет получить текущий AssetBundle, а не использовать основной набор ресурсов по умолчанию rootBundle.
Этот подход позволяет родительскому виджету заменить AssetBundle во время выполнения, что бывает полезно для локализации или сценариев тестирования.
1 import 'package:flutter/services.dart' show rootBundle;
2 import 'package:flutter/material.dart';
3
4 class MyWidget extends StatelessWidget {
5 @override
6 Widget build(BuildContext context) {
7 return FutureBuilder(
8 future: DefaultAssetBundle.of(context).loadString('assets/config.json'),
9 builder: (context, snapshot) => Text(snapshot.data ?? ''),
10 );
11 }
12 }
Иконка приложения
Обновление иконки приложения Flutter выполняется таким же образом, как обновление иконки в нативных приложениях для Android или iOS.
Android

iOS

Launch Screen
Launch Screen — первый экран, который видит пользователь. Он появляется сразу после запуска приложения и сохраняется до тех пор, пока Flutter не отрисует первый кадр приложения. Обновляется он таким же образом, как в нативных приложениях.
В Android
Для добавления экрана запуска в приложении нужно перейти в папку android/app/src/main. В файле res/drawable/launch_background.xml можно использовать layer list drawable XML-файл для кастомизации экрана запуска.
Дополнительные сведения можно найти в официальной документации.
В iOS
Чтобы добавить изображение в центр, в папку ios/Runner/Assets.xcassets/LaunchImage.imageset нужно поместить изображения с именами LaunchImage.png, LaunchImage@2x.png, LaunchImage@3x.png. Для использования других имён файлов нужно обновить файл Contents.json в ios/Runner.
Также можно полностью настроить шаблон экрана запуска в Xcode, открыв ios/Runner.xcworkspace. В навигаторе проекта нужно перейти в Runner/Runner и добавить изображения, открыв Assets.xcassets или настроив экран запуска с помощью Interface Builder в файле LaunchScreen.storyboard.
Дополнительные сведения можно найти в официальной документации.
Отлично, с ассетами разобрались — теперь вы умеете добавлять их в приложение и разбираетесь в нюансах (например, что такое pixel ratio).
В следующем параграфе мы копнём на уровень глубже и поговорим о языке Dart — как он появился, зачем был придуман, какими особенностями обладает.
