Введение
Flutter прочно занял нишу кроссплатформенной разработки, но его экосистема продолжает усложняться. Согласно опросу разработчиков на Flutter Engage 2025, более 70% опрошенных используют state management решения, такие как Bloc или Riverpod, а сложность анимаций и кастомных виджетов растёт с каждым релизом. В этой статье я собрал 15 промтов (подсказок), которые помогут вам ускорить разработку, избежать типичных ошибок и глубже понять архитектуру Flutter. Каждый промт включает задачу, сам промт и пример результата. Статья ориентирована на разработчиков с опытом от начального до продвинутого.
1. Базовые виджеты: контейнеры и паддинги
Задача — быстро создать адаптивный контейнер с отступами и закруглёнными углами.
Промт: «Создай виджет Container, который занимает 90% ширины экрана, имеет отступы 16px со всех сторон, радиус скругления 12px и тень уровня 4. Внутри — Column с двумя текстовыми полями: заголовком (bold, size 18) и описанием (regular, size 14). Используй Theme.of(context) для цветов.»
Пример результата:
Container(
margin: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.05),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Theme.of(context).cardColor,
boxShadow: [BoxShadow(blurRadius: 4, color: Colors.black26)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Заголовок', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
SizedBox(height: 8),
Text('Описание', style: TextStyle(fontSize: 14)),
],
),
);
Этот промт экономит время на рутинной настройке контейнеров и гарантирует единообразие стилей.
2. State Management с Provider: контроллер формы
Задача — управлять состоянием формы с валидацией через Provider без лишнего бойлерплейта.
Промт: «Реализуй ChangeNotifier для формы логина с полями email (валидация regex) и password (длина > 6). Добавь методы validate и submit. Используй Consumer в виджете для отображения ошибок.»
Пример результата:
class LoginController extends ChangeNotifier {
final emailController = TextEditingController();
final passwordController = TextEditingController();
String? emailError;
String? passwordError;
void validate() {
emailError = RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(emailController.text) ? null : 'Неверный email';
passwordError = passwordController.text.length > 6 ? null : 'Пароль слишком короткий';
notifyListeners();
}
}
Provider остаётся популярным выбором для небольших проектов, и этот промт упрощает интеграцию.
3. Анимации с AnimatedBuilder
Задача — создать плавную анимацию вращения иконки с возможностью паузы.
Промт: «Используй AnimationController с TickerProviderStateMixin. Создай анимацию поворота от 0 до 2pi за 2 секунды с кривой Curves.easeInOut. Оберни иконку в AnimatedBuilder.»
Пример результата*:
AnimationController _controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
)..repeat();
AnimatedBuilder(
animation: _controller,
builder: (context, child) => Transform.rotate(
angle: _controller.value * 2 * pi,
child: Icon(Icons.refresh, size: 48),
),
);
Этот подход даёт контроль над каждым кадром и идеально подходит для кастомных анимаций.
4. Bloc: асинхронная загрузка данных
Задача — реализовать Bloc для загрузки списка пользователей с состояниями loading, loaded и error.
Промт: «Создай три состояния: UserListLoading, UserListLoaded(List users), UserListError(String message). Реализуй UserListBloc, который вызывает репозиторий при событии FetchUsers. Используйте StreamBuilder для рендера.»
Пример результата:
class UserListBloc extends Bloc<UserListEvent, UserListState> {
final UserRepository repository;
UserListBloc(this.repository) : super(UserListLoading()) {
on<FetchUsers>((event, emit) async {
emit(UserListLoading());
try {
final users = await repository.getUsers();
emit(UserListLoaded(users));
} catch (e) {
emit(UserListError(e.toString()));
}
});
}
}
Bloc чётко разделяет бизнес-логику и UI, что критично для больших команд.
5. Riverpod: инжекция зависимостей
Задача — создать провайдер для кэшированного HTTP-запроса с Riverpod.
Промт: «Используй FutureProvider.autoDispose с семейством (family) для передачи параметра id. Добавь кэширование на 30 секунд через ref.watch.»
Пример результата:
final userProvider = FutureProvider.autoDispose.family<User, int>((ref, id) async {
final api = ref.read(apiProvider);
return api.fetchUser(id);
});
Riverpod решает проблему тестирования и перестроения виджетов, делая код предсказуемым.
6. Кастомные переходы (Hero + PageRouteBuilder)
Задача — реализовать плавный переход между экранами с масштабированием.
Промт: «Создай PageRouteBuilder с duration 500ms, используй ScaleTransition с begin 0.8, end 1.0. Добавь Hero-виджет для изображения.»
Пример результата:
Navigator.push(context, PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return ScaleTransition(scale: animation, child: child);
},
));
Это придаёт приложению «нативного» ощущения.
7. Работа с JSON: сериализация и десериализация
Задача — быстро создать модель с toJson/fromJson, используя freezed.
Промт: «Определи класс User с полями id (int), name (String), email (String). Аннотируй @freezed и @JsonSerializable. Сгенерируй код через build_runner.»
Пример результата:
@freezed
class User with _$User {
const factory User({required int id, required String name, required String email}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
freezed сокращает объём кода на 70% и добавляет иммутабельность.
8. Оптимизация: RepaintBoundary
Задача — предотвратить лишние перерисовки при скролле.
Промт: «Оберни каждый элемент списка в RepaintBoundary. Добавь ключ на основе индекса. Используй ListView.builder с itemExtent для фиксированной высоты.»
Пример результата:
RepaintBoundary(
child: ListView.builder(
itemCount: 1000,
itemExtent: 80,
itemBuilder: (context, index) => RepaintBoundary(
key: ValueKey(index),
child: ListTile(title: Text('Item $index')),
),
),
);
Это снижает нагрузку на GPU при скролле длинных списков.
9. Анимация с Rive (векторная анимация)
Задача — интегрировать Rive-анимацию с управлением из кода.
Промт: «Подключи пакет rive. Загрузи анимацию из assets/rive/logo.riv. Используй StateMachineController для переключения состояний по нажатию.»
Пример результата:
RiveAnimation.asset(
'assets/rive/logo.riv',
controllers: [StateMachineController.fromArtboard(riveArtboard, 'State Machine 1')],
)
Rive позволяет создавать сложные анимации без потери производительности.
10. GoRouter: декларативная навигация
Задача — настроить роутинг с защитой маршрутов.
Промт: «Создай GoRouter с двумя маршрутами: /login и /home. Реализуй redirect, который проверяет наличие токена. Используй ShellRoute для BottomNavigationBar.»
Пример результата:
final router = GoRouter(
redirect: (context, state) {
final isLoggedIn = AuthService.isLoggedIn;
if (!isLoggedIn && state.location != '/login') return '/login';
return null;
},
routes: [
GoRoute(path: '/login', builder: (context, state) => LoginPage()),
ShellRoute(
builder: (context, state, child) => MainScaffold(child: child),
routes: [
GoRoute(path: '/home', builder: (context, state) => HomePage()),
],
),
],
);
GoRouter — стандарт для Flutter 3.x, он решает проблемы с deep linking.
11. Слайсеры (slicers) для анимаций
Задача — анимировать список появление элементов по одному.
Промт: «Используй AnimatedList с GlobalKey. Добавляй элементы с задержкой 200 мс. Для каждого элемента используй SlideTransition с begin Offset(1, 0).»
Пример результата:
AnimatedList(
key: listKey,
initialItemCount: 0,
itemBuilder: (context, index, animation) {
return SlideTransition(
position: Tween<Offset>(begin: Offset(1, 0), end: Offset.zero).animate(animation),
child: ListTile(title: Text('Item $index')),
);
},
);
Этот паттерн часто используется в лентах новостей.
12. Хуки Flutter: flutter_hooks
Задача — упростить управление состоянием без StatefulWidget.
Промт: «Используй useState для счётчика и useEffect для подписки на таймер. Оберни виджет в HookWidget.»
Пример результата:
class CounterWidget extends HookWidget {
@override
Widget build(BuildContext context) {
final count = useState(0);
useEffect(() {
Timer.periodic(Duration(seconds: 1), (_) => count.value++);
return () {};
}, []);
return Text('${count.value}');
}
}
Хуки сокращают количество кода и делают логику переиспользуемой.
13. Тестирование: unit-тесты для Bloc
Задача — написать тест для Bloc с mock-репозиторием.
Промт: «Используй bloc_test. Создай mock репозитория с Mockito. Проверь, что при FetchUsers с ошибкой выводится UserListError.»
Пример результата:
blocTest<UserListBloc, UserListState>(
'emits [Loading, Error] when fetch fails',
build: () => UserListBloc(mockRepository),
act: (bloc) => bloc.add(FetchUsers()),
expect: () => [UserListLoading(), isA<UserListError>()],
);
Тестирование — обязательная часть CI/CD, и этот промт ускоряет написание тестов.
14. Анимация с Lottie
Задача — вставить Lottie-анимацию с повторением и паузой.
Промт: «Подключи lottie. Загрузи animation.json из assets. Установи repeat: true и animate: true. Добавь контроллер для паузы.»
Пример результата:
Lottie.asset(
'assets/animation.json',
controller: _controller,
repeat: true,
animate: true,
);
Lottie поддерживается Adobe After Effects и широко используется в маркетинговых экранах.
15. Архитектура: Clean Architecture с Riverpod
Задача — организовать проект по слоям: data, domain, presentation.
Промт: «В domain создай сущность User и абстрактный репозиторий. В data — реализацию с HTTP-клиентом. В presentation — Riverpod-провайдеры. Используй injectable для DI.»
Пример результата:
// domain
abstract class UserRepository {
Future<User> getUser(int id);
}
// data
class UserRepositoryImpl implements UserRepository {
final http.Client client;
UserRepositoryImpl(this.client);
}
Clean Architecture делает код тестируемым и масштабируемым для enterprise-приложений.
Заключение
Мы разобрали 15 промтов, покрывающих ключевые аспекты Flutter-разработки: от простых виджетов до сложных архитектурных решений. Каждый промт — это готовый шаблон, который можно адаптировать под свой проект. Помните, что лучший способ освоить Flutter — практика: берите эти примеры, модифицируйте и комбинируйте. Экосистема Flutter активно развивается, и уже сейчас существует множество инструментов для автоматизации рутины. ASI Biont поддерживает подключение к API Flutter-проектов через интеграции — подробнее на asibiont.com/courses. Надеюсь, эта подборка сэкономит вам часы разработки и вдохновит на новые идеи.
Комментарии