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 — как он появился, зачем был придуман, какими особенностями обладает.