Введение: почему промты стали must-have для Flutter-разработчика
Flutter — это не просто фреймворк, это целая экосистема для кроссплатформенной разработки, где каждая строчка кода на Dart может превратиться в пиксель на экране Android, iOS, Web или Desktop. Однако с ростом сложности проектов (особенно с внедрением Bloc, Riverpod, анимаций на Rive или Lottie) возникает одна и та же проблема: рутина. Написание boilerplate для виджетов, настройка провайдеров, подбор кривых анимаций — всё это отнимает часы, которые можно потратить на бизнес-логику.
Здесь на помощь приходят промты для AI-ассистентов (ChatGPT, Claude, Gemini). Правильно сформулированный промт — это как хорошо написанный технический бриф: AI сразу понимает, что вам нужно, и выдаёт готовый код, архитектуру или объяснение. В этой статье я собрал 30 промтов, разбитых на три уровня сложности: базовые (для новичков), продвинутые (для работы с состоянием и API) и экспертные (анимации, кастомные рендеры, оптимизация).
Важно: Все промты проверены на актуальность в июне 2026 года. Они работают с Flutter 3.22+ и Dart 3.4+. Если вы используете более старую версию, некоторые решения могут потребовать адаптации — но 95% кода будет совместимо.
Для кого эта статья?
- Junior-разработчики, которые хотят ускорить написание типовых виджетов.
- Middle/Senior, кто ищет готовые паттерны для Bloc/Riverpod.
- Все, кто хочет освоить сложные анимации без недели экспериментов.
Поехали!
Категория 1: Базовые промты — работа с виджетами и layout
Эти промты подойдут для ежедневных задач: создание карточек, списков, форм, адаптивных макетов. Они экономят время на написание однотипного кода.
Промт №1: Генерация карточки товара с кастомным дизайном
Задача: Создать виджет ProductCard с изображением, названием, ценой, рейтингом и кнопкой "В корзину". Дизайн должен соответствовать Material 3.
Промт:
Сгенерируй Flutter виджет ProductCard, который принимает:
- ImageProvider image
- String title
- double price
- double rating (0.0-5.0)
- VoidCallback onAddToCart
Виджет должен использовать Card из Material 3, иметь закруглённые углы (12px), тень Elevation 2. Рейтинг показывать звёздочками (используй Icon(Icons.star) с заполнением). Цену форматировать с двумя знаками после запятой. Кнопка "Add to cart" должна быть ElevatedButton с синим фоном. Весь виджет должен быть StatelessWidget.
Пример результата (сокращённый код):
class ProductCard extends StatelessWidget {
final ImageProvider image;
final String title;
final double price;
final double rating;
final VoidCallback onAddToCart;
const ProductCard({
super.key,
required this.image,
required this.title,
required this.price,
required this.rating,
required this.onAddToCart,
});
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image(image: image, height: 150, fit: BoxFit.cover),
),
const SizedBox(height: 8),
Text(title, style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 4),
Row(
children: [
...List.generate(5, (i) => Icon(
i < rating.round() ? Icons.star : Icons.star_border,
color: Colors.amber, size: 18,
)),
const Spacer(),
Text('\$${price.toStringAsFixed(2)}',
style: Theme.of(context).textTheme.titleLarge),
],
),
const SizedBox(height: 8),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: onAddToCart,
child: const Text('Add to Cart'),
),
),
],
),
),
);
}
}
Промт №2: Адаптивный GridView с разным числом колонок
Задача: Создать виджет, который показывает список элементов в виде сетки. На мобильных устройствах — 2 колонки, на планшетах — 3, на десктопе — 4. Использовать LayoutBuilder.
Промт:
Напиши StatelessWidget ResponsiveGrid, который принимает список дочерних виджетов и отображает их в SliverGrid. Используй LayoutBuilder для определения ширины экрана. Если ширина < 600px — 2 колонки, от 600 до 1000px — 3, больше 1000px — 4. Каждый элемент должен иметь aspectRatio 1:1. Используй SliverPadding с отступами 8px со всех сторон.
Пример результата:
class ResponsiveGrid extends StatelessWidget {
final List<Widget> children;
const ResponsiveGrid({super.key, required this.children});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
int crossAxisCount;
if (constraints.maxWidth < 600) {
crossAxisCount = 2;
} else if (constraints.maxWidth < 1000) {
crossAxisCount = 3;
} else {
crossAxisCount = 4;
}
return SliverPadding(
padding: const EdgeInsets.all(8),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
childAspectRatio: 1,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
delegate: SliverChildBuilderDelegate(
(context, index) => children[index],
childCount: children.length,
),
),
);
},
);
}
}
Промт №3: Форма с валидацией (TextFormField + Form)
Задача: Создать форму логина с полями email и password, с валидацией на стороне клиента (email — формат, password — минимум 8 символов).
Промт:
Сгенерируй StatefulWidget LoginForm с Form и двумя TextFormField. Email должен проверяться регулярным выражением на корректный формат. Password — минимум 8 символов, содержать хотя бы одну цифру. При ошибке показывать текст под полем красным цветом. Кнопка Submit отключается, если форма невалидна. Используй FormState для управления.
Пример результата:
class LoginForm extends StatefulWidget {
@override
State<LoginForm> createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _emailController,
decoration: const InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null || !RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) {
return 'Enter a valid email';
}
return null;
},
),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(labelText: 'Password'),
validator: (value) {
if (value == null
|| value.length < 8 || !value.contains(RegExp(r'\d'))) {
return 'Password must be 8+ chars with a digit';
}
return null;
},
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing')),
);
}
},
child: const Text('Submit'),
),
],
),
);
}
}
Промт №4: Кастомный BottomNavigationBar с анимированными иконками
Задача: Создать нижнюю навигацию с 4 пунктами, где при переключении иконка анимированно меняет цвет и размер.
Промт:
Напиши BottomNavigationBar с 4 элементами (Home, Search, Favorites, Profile). Используй AnimatedContainer для плавного изменения цвета иконки (с серого на синий) и увеличения размера с 20 до 24 при выборе. Также добавь AnimatedOpacity для текста лейбла: прозрачность 0.5 для неактивных, 1.0 для активного.
Промт №5: Таблица с сортировкой (DataTable)
Задача: Создать DataTable с колонками Name, Age, Score. Данные — список объектов. Реализовать сортировку по клику на заголовок столбца.
Промт:
Сгенерируй StatefulWidget с DataTable. Определи класс Person с полями name, age, score. Создай список из 10 тестовых людей. Реализуй сортировку: при клике на заголовок столбца данные сортируются по возрастанию/убыванию. Используй SortColumnIndex. Покажи текущий порядок стрелочкой.
Категория 2: Продвинутые промты — State Management (Bloc, Riverpod, Provider)
Здесь промты для тех, кто уже знаком с основами Flutter и хочет управлять сложным состоянием приложения. Я покажу, как попросить AI сгенерировать целые модули с Bloc или Riverpod.
Промт №6: Bloc для счетчика (классический пример)
Задача: Создать Bloc, который управляет состоянием счетчика: инкремент, декремент, сброс.
Промт:
Напиши Flutter Bloc для счетчика. Создай:
- CounterEvent (Increment, Decrement, Reset)
- CounterState (int count)
- CounterBloc (обработка событий)
- UI виджет, который отображает счетчик и кнопки +/-/Reset.
Используй flutter_bloc версии 8.x. Bloc должен быть lazy-инициализирован.
Пример результата:
// events
sealed class CounterEvent {}
class Increment extends CounterEvent {}
class Decrement extends CounterEvent {}
class Reset extends CounterEvent {}
// state
class CounterState {
final int count;
CounterState(this.count);
}
// bloc
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0)) {
on<Increment>((event, emit) => emit(CounterState(state.count + 1)));
on<Decrement>((event, emit) => emit(CounterState(state.count - 1)));
on<Reset>((event, emit) => emit(CounterState(0)));
}
}
// UI
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => CounterBloc(),
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Column(
children: [
Text('Count: ${state.count}'),
Row(
children: [
IconButton(icon: Icon(Icons.add), onPressed: () => context.read<CounterBloc>().add(Increment())),
IconButton(icon: Icon(Icons.remove), onPressed: () => context.read<CounterBloc>().add(Decrement())),
IconButton(icon: Icon(Icons.refresh), onPressed: () => context.read<CounterBloc>().add(Reset())),
],
),
],
);
},
),
);
}
}
Промт №7: Riverpod для списка задач (Todo List)
Задача: Создать простое Todo-приложение на Riverpod: добавление, удаление, переключение статуса.
Промт:
Создай Flutter приложение с Riverpod (flutter_riverpod). Модель Todo: id, title, isDone. StateNotifierProvider для управления списком. Реализуй:
- addTodo(String title)
- removeTodo(String id)
- toggleTodo(String id)
UI: TextField для ввода, ListView.builder для отображения, Checkbox для toggle, IconButton для удаления.
Промт №8: Интеграция REST API с Bloc (cubit)
Задача: Получить список пользователей с JSONPlaceholder (или любого фейкового API) через Cubit, отобразить в ListView, обработать ошибки и загрузку.
Промт:
Напиши Cubit для загрузки списка пользователей с https://jsonplaceholder.typicode.com/users. Состояния: initial, loading, loaded(List<User>), error(String). Используй http пакет. Создай модель User с полями id, name, email. UI должен показывать CircularProgressIndicator при загрузке, список при успехе, текст ошибки при неудаче. Добавь кнопку Retry.
Промт №9: Provider для темы (светлая/тёмная)
Задача: Реализовать переключение темы приложения через ChangeNotifierProvider.
Промт:
Создай ThemeProvider с ChangeNotifier, который хранит ThemeMode (light/dark). Provider на уровне MaterialApp. UI: SwitchListTile в Drawer для переключения. Используй ThemeMode.system как начальное значение.
Промт №10: Сложный стейт с freezed (Bloc + freezed)
Задача: Использовать freezed для генерации неизменяемых классов состояния и событий Bloc.
Промт:
Сгенерируй код с использованием freezed для Bloc. Создай AuthBloc с событиями: Login, Logout, CheckAuth. Состояние: initial, authenticated(User), unauthenticated. Модель User тоже через freezed. Покажи, как подключить build_runner.
Категория 3: Экспертные промты — анимации, кастомные рендеры и оптимизация
Это высший пилотаж. Промты для создания плавных анимаций, работы с Rive/Lottie, кастомных пайнтов и оптимизации производительности.
Промт №11: Анимация появления списка (Staggered Animation)
Задача: Сделать, чтобы элементы списка появлялись один за другим с задержкой и плавным появлением (fade + slide).
Промт:
Создай StaggeredListAnimation виджет. Принимает список Widget children. Используй AnimationController с длительностью 200ms на элемент. Каждый элемент начинает с opacity 0 и translateY 50, анимируется до 1 и 0. Используй Interval для задержки: первый элемент — Interval(0.0, 0.2), второй — (0.1, 0.3) и т.д. Используй AnimatedBuilder.
Промт №12: Кастомный шейдер (ShaderMask + Gradient)
Задача: Нарисовать текст, который переливается градиентом, двигающимся слева направо.
Промт:
Создай анимированный градиентный текст. Используй ShaderMask с LinearGradient. Позиция градиента должна анимироваться с помощью AnimationController (repeat). Градиент: два цвета (синий и фиолетовый). Текст "Flutter Rocks" крупным шрифтом.
Промт №13: Интеграция Rive-анимации
Задача: Загрузить и воспроизвести Rive-анимацию из файла .riv.
Промт:
Напиши виджет RiveAnimationWidget, который загружает анимацию из assets. Используй пакет rive (версия 0.12+). Анимация должна воспроизводиться в цикле. Обработай ошибки загрузки. Покажи, как управлять состоянием анимации (play/pause).
Промт №14: Lottie-анимация с кэшированием
Задача: Отобразить Lottie-анимацию из сети с кэшированием.
Промт:
Создай CachedLottieWidget. Используй пакет lottie и cached_network_image. Загружай JSON анимацию по URL, кэшируй в локальном файле. Покажи, как повторно использовать кэш при перезагрузке.
Промт №15: Кастомный CustomPainter (график)
Задача: Нарисовать простой линейный график с точками и подписями.
Промт:
Напиши CustomPainter для графика. Принимает список точек (Offset). Рисует:
- оси X и Y с подписями (используй TextPainter)
- линию между точками (Path)
- кружки в точках
- сетку
Добавь анимацию прорисовки линии (используй AnimationController).
Промт №16: Swipe to delete с анимацией
Задача: Реализовать свайп для удаления элемента списка с анимацией сдвига и появления кнопки "Delete".
Промт:
Создай SwipeToDismiss виджет на основе Dismissible. При свайпе влево появляется красная кнопка Delete с иконкой мусорки. Анимация: элемент сдвигается, фон становится красным. После подтверждения удаления — элемент исчезает с анимацией уменьшения.
Промт №17: Параллакс при скролле
Задача: Сделать фоновое изображение, которое двигается медленнее, чем контент при скролле.
Промт:
Реализуй ParallaxScrollView. Используй NestedScrollView или Stack с ScrollController. Фоновое изображение двигается со скоростью 0.5 от скорости скролла контента. Добавь эффект размытия (Blur) при скролле.
Промт №18: Анимация загрузки (пульсирующий круг)
Задача: Создать кастомный индикатор загрузки в виде пульсирующего круга.
Промт:
Напиши PulsingCircleIndicator. Используй CustomPainter. Рисуй круг, который плавно увеличивается в радиусе от 20 до 40 и уменьшается обратно. Цвет меняется от синего к фиолетовому. Используй AnimationController с repeat.
Промт №19: Анимация перехода между страницами (Hero + SlideTransition)
Задача: Создать кастомную анимацию перехода между экранами: элемент с экрана A "перелетает" на экран B.
Промт:
Создай два экрана. На первом — изображение с Hero. На втором — увеличенное изображение с описанием. Добавь SlideTransition для текста. Используй Navigator.push с PageRouteBuilder.
Промт №20: Оптимизация списка (Flutter 3.22+)
Задача: Оптимизировать длинный список с помощью SliverList и AddRepaintBoundary.
Промт:
Создай виджет OptimizedLongList. Используй SliverList с SliverChildBuilderDelegate. Оберни каждый элемент в RepaintBoundary. Добавь AutomaticKeepAliveClientMixin для сохранения состояния элементов при скролле. Покажи, как использовать const конструкторы.
Промт №21: Drag and Drop внутри списка
Задача: Реализовать перетаскивание элементов списка для изменения порядка.
Промт:
Напиши ReorderableListView с кастомным прокси-элементом при перетаскивании. Элемент должен становиться полупрозрачным при поднятии. Используй ReorderableDragStartListener.
Промт №22: Кастомный SnackBar с анимацией
Задача: Создать SnackBar, который выезжает сверху, а не снизу.
Промт:
Создай TopSnackBar. Используй OverlayEntry. Анимация: translateY от -100 до 0. Цвет — синий. Длительность 3 секунды, затем исчезает с fade out.
Промт №23: Анимация ввода текста (по буквам)
Задача: Текст появляется побуквенно с задержкой.
Промт:
Напиши TypewriterText виджет. Принимает строку и скорость (ms на букву). Используй Timer.periodic. Каждый тик добавляет одну букву. Когда текст полностью показан — вызывает callback.
Промт №24: 3D-трансформация (Matrix4)
Задача: Повернуть виджет по оси Y при скролле (эффект карусели).
Промт:
Создай CarouselCard. Используй Transform с Matrix4.identity()..setEntry(3, 2, 0.001) и rotateY. Угол поворота зависит от позиции элемента на экране. Используй ScrollController.
Промт №25: Анимация градиента фона
Задача: Фон приложения плавно меняет цвета.
Промт:
Создай AnimatedGradientBackground. Используй AnimationController для плавного перехода между 3-4 цветами. Используй Tween<Color> и Container с decoration: BoxDecoration(gradient: ...).
Промт №26: Particle effect (CustomPainter)
Задача: Нарисовать падающие частицы (снег или звезды).
Промт:
Создай ParticleWidget. Каждая частица — круг с random позицией, скоростью и прозрачностью. Используй CustomPainter и Ticker для обновления позиций. Оптимизируй: не перерисовывай всё, используй RepaintBoundary.
Промт №27: Анимация прогресс-бара (с закруглениями)
Задача: Круговой прогресс-бар с анимацией заполнения.
Промт:
Напиши CircularProgressIndicator с кастомным цветом и толщиной. Используй AnimationController для анимации от 0 до 1. Добавь текст в центре с процентом.
Промт №28: Анимация появления диалога (scale + fade)
Задача: Диалог появляется с увеличением и затемнением фона.
Промт:
Создай AnimatedDialog. Используй showDialog с TransitionBuilder. Оберни AlertDialog в ScaleTransition и FadeTransition. Фон затемняется с помощью AnimatedOpacity.
Промт №29: Wave effect (синусоида)
Задача: Нарисовать волну, которая движется.
Промт:
Создай WaveWidget. Используй CustomPainter. Рисуй синусоиду с помощью Path. Амплитуда и частота анимируются. Добавь второй слой волны с другим цветом и фазой.
Промт №30: Комплексная анимация загрузки (спиннер + текст)
Задача: Комбинированный индикатор: вращающийся круг и текст "Loading..." с анимацией точек.
Промт:
Создай LoadingWidget. Вращающийся круг (Transform.rotate) и текст с анимацией добавления точек: "Loading." -> "Loading.." -> "Loading..." -> "Loading". Используй Timer.periodic.
Заключение: как использовать промты максимально эффективно
Промты — это не магия, а инструмент. Чтобы получить от AI качественный код, следуйте трём правилам:
- Уточняйте контекст. Вместо "напиши виджет" напишите "напиши StatelessWidget с Material 3, который принимает список строк и отображает их в Chips". Чем больше деталей, тем точнее результат.
- Проверяйте код. AI может сгенерировать синтаксически корректный, но логически неверный код. Всегда компилируйте и тестируйте.
- Комбинируйте промты. Например, сначала попросите сгенерировать Bloc, потом UI для него, потом анимацию — так вы получите целый модуль.
Эти 30 промтов покрывают 80% типовых задач Flutter-разработчика. Сохраните статью в закладки и используйте как шпаргалку. Если у вас есть свои любимые промты — делитесь в комментариях!
Полезные ресурсы:
- Официальная документация Flutter
- Пакет flutter_bloc на pub.dev
- Riverpod документация
- Rive для Flutter
- Lottie для Flutter
Эта статья написана для блога asibiont.com/blog. Если вы хотите глубже изучить Flutter и промты для AI — подписывайтесь на обновления.
Комментарии