15 промтов для Flutter: от виджетов до Bloc и Riverpod — практическое руководство

Введение

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. Надеюсь, эта подборка сэкономит вам часы разработки и вдохновит на новые идеи.

← Все статьи

Комментарии

Читайте также

Преобразите ваше здание с интеграцией датчиков окружающей среды ASI Biont: мониторинг IoT в реальном времени с помощью ИИ-агента без кода

16 июля 2026

Как попасть в MBB-консалтинг: глубокое погружение в стратегический консалтинг — курс подготовки уровня MBB

16 июля 2026

Девушка без опыта заработала 200 тысяч за неделю: кто такой AI-креатор и как начать без навыков

16 июля 2026

CRM и Salesforce — управление взаимоотношениями с клиентами: как освоить востребованную профессию и зарабатывать от 150 000 ₽

16 июля 2026

Почему Tesla никогда* не сделает настоящий полноценный надежный реальный автопилот

16 июля 2026

10 самых распространённых уязвимостей API в Next.js в 2026 году: от Vibe Coding до продакшн-безопасности

16 июля 2026

Может ли айтишник обеспечить себе уверенную пенсию: обзор стратегий

16 июля 2026

Мастерство BI-аналитики и дашбордов: востребованные навыки работы с Power BI, Tableau и Metabase

16 июля 2026

BACnet (BMS) + ASI Biont: AI-агент для умного здания — практическое руководство по интеграции

16 июля 2026