Файл кода
В проект можно добавлять свои файлы на Dart с классами и перечислениями. Из них получаются собственные типы данных: их поля выводятся в интерфейсе, методы вызываются в потоке действий.
Где применяется
- Свои модели данных —
UserProfile,Product,Order. - Бизнес-логика — расчёт налога, форматирование, проверки.
- Перечисления — фиксированные наборы значений для условий и выпадающих списков.
- Обобщённые типы. Классы с параметрами типа (
class ApiResponse<T> {}) не разбираются. - Параметры-функции. Поля и параметры функционального типа игнорируются (
void Function(int) onTap). - Расширения. Dart extensions (
extension StringX on String { … }) пока не поддерживаются.
Создание класса
Откройте Custom Code в меню слева, нажмите плюс (+) и выберите Code File. Задайте имя файла, вставьте код и нажмите Save. Затем нажмите validate — редактор поймает синтаксические ошибки. Если их нет, нажмите Parse: FlutterFlow разберёт код и найдёт классы и перечисления.
Пример с классом Review:
Его код:
class Review {
String id;
String productId;
String userId;
String userName;
String comment;
double rating; // из 5
ReviewStatus reviewStatus;
DateTime date;
int helpfulCount = 0;
Review(
this.id,
this.productId,
this.userId,
this.userName,
this.comment,
this.rating,
this.reviewStatus,
this.date,
);
// Короткая версия комментария
String shortComment() {
if (comment.length <= 50) return comment;
return comment.substring(0, 47) + "...";
}
// Дата строкой в виде "2024-05-22"
String formattedDate() {
return "${date.year}-${_twoDigits(date.month)}-${_twoDigits(date.day)}";
}
String _twoDigits(int n) {
return n >= 10 ? "$n" : "0$n";
}
// Отзыв положительный, если 4 звезды и больше
bool isPositive() {
return rating >= 4.0;
}
// Отзыв свежий, если ему меньше 30 дней
bool isRecent() {
final now = DateTime.now();
return now.difference(date).inDays <= 30;
}
// Отметить отзыв полезным
void markHelpful() {
helpfulCount += 1;
}
}
В файле класса можно писать импорты и обращаться к сгенерированным классам проекта — см. примеры.
Создание экземпляра
Класс сам по себе данных не содержит — с ними работает его экземпляр.
-
Класс — чертёж. Класс
Reviewописывает, что такое отзыв, но ни одного отзыва в себе не держит. -
Экземпляр (объект) — конкретный отзыв, сделанный по этому чертежу:
Review review1 = Review( 'r001', 'p123', 'u456', 'Alex Morgan', 'Great quality T-shirt!', 4.5, DateTime(2025, 5, 22), 3, ReviewStatus.approved, ); -
Во FlutterFlow экземпляр хранится в переменной состояния приложения, страницы или компонента.
-
Экземпляров одного класса может быть сколько угодно — с разными данными.
С экземпляром можно:
- хранить конкретные данные;
- читать и менять поля (
review1.rating,review1.comment); - вызывать методы (
review1.markHelpful(),review1.shortComment()).
Порядок такой: создайте переменную состояния типа своего класса, откройте Set from Variable и выберите Create Custom Class Instance. Укажите класс, выберите конструктор в списке Constructor и заполните обязательные поля.
Работа с классом
После разбора класс становится доступен в диалоге переменных: его поля выводятся в интерфейсе, методы вызываются в потоке действий, экземпляры кладутся в переменные состояния и передаются параметрами страниц и компонентов.
Класс как тип данных
Свой класс выбирается типом переменной, состояния или параметра — так же, как собственный тип данных.

Поля и методы
Поля выводятся в интерфейсе напрямую, а методы вызываются в диалоге переменных и возвращают результат.

Действие Set Field
Set Field меняет значение поля экземпляра. Например, review.comment = 'Great fit and quality!' — и интерфейс сразу показывает новый комментарий.
Действие Call Method
Call Method вызывает метод класса. Скажем, метод markHelpful() срабатывает по нажатию кнопки «Полезно».
Статические члены
Статические поля и методы принадлежат самому классу, а не экземпляру, — поэтому доступны везде и без создания объекта. Это подходит для утилит: форматирования, расчётов, глобальных настроек.
class Utils {
static int square(int x) => x * x;
}
Метод square возвращает квадрат числа, и объект класса Utils для этого не нужен.
Ещё пара примеров:
-
StringFormatter— набор методов для работы со строками.class StringFormatter { static String lastFormatted = ''; static int formatCount = 0; static String capitalize(String input) => input[0].toUpperCase() + input.substring(1); static String toLowerCase(String input) => input.toLowerCase(); static String toSnakeCase(String input) => input.replaceAll(' ', '_').toLowerCase(); } -
MathHelper— расчёт налога, скидки, доли и округление.class MathHelper { static double calculateTax(double amount) => amount * 0.18; static double applyDiscount(double amount, double discountPercent) => amount - (amount * discountPercent / 100); static double calculatePercentage(double part, double total) => (part / total) * 100; static int roundOff(double value) => value.round(); }
Статические и обычные члены уживаются в одном классе: статические общие для всех экземпляров, обычные хранят данные конкретного объекта.
class Review {
static List<String> flaggedWords = ['bad', 'spam', 'fake'];
String id;
String userId;
String comment;
int helpfulCount = 0;
Review(
this.id,
this.userId,
this.comment
);
static bool isCommentAppropriate(String input) {
return !flaggedWords.any((word) => input.toLowerCase().contains(word));
}
void markHelpful() {
helpfulCount += 1;
}
}flaggedWords— общий список для всех отзывов.isCommentAppropriate()вызывается без создания экземпляра — например, чтобы проверить комментарий до сохранения.
Со статическими членами легко переусердствовать. Они не видят состояния конкретного объекта и хуже поддаются изменению по мере развития проекта. Делайте статическим только то, что действительно ни от чего не зависит.
Доступ к статическим членам
Статические поля и методы доступны напрямую в меню Set from Variable.

Действие Set Static Field
Set Static Field записывает значение в статическое поле. Например, класс MathHelper со статическим полем amount может хранить введённую пользователем сумму, доступную всем расчётам.
Действие Call Static Method
Call Static Method вызывает статический метод. Скажем, MathHelper.calculateTax(amount) считает налог при оформлении заказа — экземпляр класса для этого не нужен.
Свои перечисления
Перечисления добавляются так же, как классы, и задают фиксированный набор значений: роли пользователей, статусы заказа, типы содержимого. После разбора они доступны в выпадающих списках, условиях и привязках.
Например, ReviewStatus со значениями pending, approved и rejected:
enum ReviewStatus {
pending,
approved,
rejected,
}

Обращаются к ним через Set from Variable > Custom Enum: там будет ваш файл, внутри — перечисление и его значения.
Что стоит учесть
- Держите файлы небольшими — в идеале один класс на файл.
- Не используйте то, что парсер FlutterFlow не разбирает: обобщённые типы, поля функционального типа.
- После правки кода запускайте разбор заново, иначе FlutterFlow работает со старой структурой.
- Комментируйте код: через полгода это единственное, что объяснит логику.
Частые вопросы
Можно ли добавлять файлы кода в проект-библиотеку?
Да. При подключении библиотеки её файлы кода разбираются, и классы становятся доступны в проекте, который её использует.