10 промтов для Flutter: от виджетов до state management и анимаций

10 промтов для Flutter: от виджетов до state management и анимаций

Flutter — это популярный фреймворк для создания кроссплатформенных приложений. С помощью правильно составленных промтов вы можете ускорить разработку, автоматизировать рутинные задачи и углубить понимание фреймворка. В этой подборке мы собрали 10 практичных промтов, которые охватывают виджеты, анимации, управление состоянием и тестирование. Каждый промт сопровождается примером использования и кодом, который легко адаптировать под свой проект.

Эти промты основаны на официальной документации Flutter (Flutter Widgets, State Management) и опыте разработчиков, поэтому вы можете доверять их корректности.

1. Генерация виджета с валидацией email

Промт: Сгенерируй Flutter виджет для ввода email с валидацией. Используй TextFormField, Form и соответствующие валидаторы. Предоставь полный код на Dart с комментариями.

Зачем: Этот промт позволяет быстро получить рабочий код формы с валидацией, не тратя время на написание рутины.

Пример использования: Вы копируете промт в AI-инструмент, получаете код, вставляете в свой проект. Ниже — один из вариантов результата.

import 'package:flutter/material.dart';

class EmailForm extends StatefulWidget {
  @override
  _EmailFormState createState() => _EmailFormState();
}

class _EmailFormState extends State<EmailForm> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();

  @override
  void dispose() {
    _emailController.dispose();
    super.dispose();
  }

  String? _validateEmail(String? value) {
    if (value == null || value.isEmpty) {
      return 'Введите email';
    }
    final emailRegex = RegExp(r'^[^@]+@[^@]+\.[^@]+$');
    if (!emailRegex.hasMatch(value)) {
      return 'Введите корректный email';
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: TextFormField(
        controller: _emailController,
        decoration: const InputDecoration(labelText: 'Email'),
        validator: _validateEmail,
      ),
    );
  }
}

2. Разница между StatefulWidget и StatelessWidget

Промт: Объясни разницу между StatefulWidget и StatelessWidget в Flutter. Приведи наглядный пример для каждого случая.

Зачем: Понимание этой разницы — основа Flutter-разработки. Промт помогает быстро получить объяснение с примерами.

Пример использования: Вы получаете развернутый ответ. Ключевое отличие: StatelessWidget неизменяем, а StatefulWidget хранит состояние и может перестраиваться при его изменении.

// StatelessWidget — статичный виджет
class MyStateless extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Я не меняюсь');
  }
}

// StatefulWidget — виджет с состоянием
class MyStateful extends StatefulWidget {
  @override
  _MyStatefulState createState() => _MyStatefulState();
}

class _MyStatefulState extends State<MyStateful> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Счётчик: $_counter'),
        ElevatedButton(
          onPressed: () => setState(() => _counter++),
          child: Text('Увеличить'),
        ),
      ],
    );
  }
}

3. Анимация появления элемента

Промт: Напиши код для плавного появления элемента при нажатии кнопки. Используй AnimatedOpacity и AnimatedContainer.

Зачем: Анимации делают интерфейс живым. Этот промт даёт рабочий пример для встраивания анимаций.

Пример использования: Код кнопки, которая плавно показывает/скрывает блок и меняет его размер.

import 'package:flutter/material.dart';

class AnimatedDemo extends StatefulWidget {
  @override
  _AnimatedDemoState createState() => _AnimatedDemoState();
}

class _AnimatedDemoState extends State<AnimatedDemo> {
  bool _visible = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: () => setState(() => _visible = !_visible),
          child: Text('Показать/скрыть'),
        ),
        AnimatedOpacity(
          opacity: _visible ? 1.0 : 0.0,
          duration: Duration(milliseconds: 500),
          child: AnimatedContainer(
            duration: Duration(milliseconds: 500),
            width: _visible ? 200 : 100,
            height: _visible ? 200 : 100,
            color: Colors.blue,
            child: Center(child: Text('Контент')),
          ),
        ),
      ],
    );
  }
}

4. Переход с setState на Provider

Промт: Как перевести Flutter-приложение с setState на Provider? Покажи пример с ChangeNotifier.

Зачем: Provider — популярное решение для управления состоянием. Промт поможет мигрировать существующий код.

Пример использования: Создаем модель-счётчик, подключаем ChangeNotifier и используем его в виджетах с помощью Provider.of.

// 1. Модель
class CounterModel extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

// 2. В main.dart
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => CounterModel(),
      child: MyApp(),
    ),
  );
}

// 3. В виджете
class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = Provider.of<CounterModel>(context);
    return Scaffold(
      body: Center(
        child: Text('${counter.count}'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: counter.increment,
        child: Icon(Icons.add),
      ),
    );
  }
}

5. Riverpod для списка задач

Промт: Создай пример использования Riverpod для управления состоянием списка задач. Используй StateProvider и FutureProvider.

Зачем: Riverpod — развивающаяся библиотека управления состоянием, которая устраняет недостатки Provider.

Пример использования: StateProvider для списка, FutureProvider для асинхронной загрузки.

final tasksProvider = StateProvider<List<String>>((ref) => []);
final fetchTasksProvider = FutureProvider<List<String>>((ref) async {
  await Future.delayed(Duration(seconds: 2));
  return ['Задача 1', 'Задача 2'];
});

class TasksList extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final tasks = ref.watch(tasksProvider);
    final asyncTasks = ref.watch(fetchTasksProvider);
    return Column(
      children: [
        Expanded(
          child: asyncTasks.when(
            data: (data) => ListView.builder(
              itemCount: data.length,
              itemBuilder: (ctx, i) => ListTile(title: Text(data[i])),
            ),
            loading: () => CircularProgressIndicator(),
            error: (err, _) => Text('Ошибка: $err'),
          ),
        ),
      ],
    );
  }
}

6. BLoC для аутентификации

Промт: Напиши BLoC-класс для аутентификации пользователя, используя Equatable и dart_bloc.

Зачем: BLoC (Business Logic Component) — ещё один мощный подход к управлению состоянием, часто используется в больших проектах.

Пример использования: Событие и состояние, BLoC-класс с обработкой.

// Событие
abstract class AuthEvent extends Equatable {
  const AuthEvent();
  @override
  List<Object?> get props => [];
}

class LoginEvent extends AuthEvent {
  final String email;
  final String password;
  const LoginEvent(this.email, this.password);
  @override
  List<Object?> get props => [email, password];
}

// Состояние
abstract class AuthState extends Equatable {
  const AuthState();
  @override
  List<Object?> get props => [];
}

class AuthInitial extends AuthState {}
class AuthLoading extends AuthState {}
class AuthSuccess extends AuthState {}
class AuthFailure extends AuthState {
  final String message;
  const AuthFailure(this.message);
  @override
  List<Object?> get props => [message];
}

// BLoC
class AuthBloc extends Bloc<AuthEvent, AuthState> {
  AuthBloc() : super(AuthInitial()) {
    on<LoginEvent>((event, emit) async {
      emit(AuthLoading());
      try {
        // Представим, что здесь вызов API
        await Future.delayed(Duration(seconds: 1));
        emit(AuthSuccess());
      } catch (e) {
        emit(AuthFailure(e.toString()));
      }
    });
  }
}

7. Бесконечный список с пагинацией

Промт: Создай кастомный виджет для бесконечного списка с загрузкой данных, используя ScrollController и FutureBuilder.

Зачем: Пагинация необходима при работе с большими данными. Этот промт даёт готовый шаблон.

Пример использования: При прокрутке вниз подгружается следующая страница.

import 'package:flutter/material.dart';

class PaginatedList extends StatefulWidget {
  @override
  _PaginatedListState createState() => _PaginatedListState();
}

class _PaginatedListState extends State<PaginatedList> {
  final _scrollController = ScrollController();
  final _items = <String>[];
  bool _isLoading = false;
  int _page = 1;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
    _loadMore();
  }

  Future<void> _loadMore() async {
    if (_isLoading) return;
    setState(() => _isLoading = true);
    // Имитация запроса
    await Future.delayed(Duration(seconds: 2));
    final newItems = List.generate(10, (i) => 'Элемент ${_page * 10 + i}');
    setState(() {
      _items.addAll(newItems);
      _page++;
      _isLoading = false;
    });
  }

  void _onScroll() {
    if (_scrollController.position.pixels >=
        _scrollController.position.maxScrollExtent - 100) {
      _loadMore();
    }
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      controller: _scrollController,
      itemCount: _items.length + (_isLoading ? 1 : 0),
      itemBuilder: (context, index) {
        if (index >= _items.length) {
          return Center(child: CircularProgressIndicator());
        }
        return ListTile(title: Text(_items[index]));
      },
    );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }
}

8. Юнит-тесты для валидации и виджета-счётчика

Промт: Напиши юнит-тесты для функции валидации email и для простого виджета-счётчика, используя flutter_test.

Зачем: Тестирование — важная часть разработки. Промт помогает быстро создать тестовые сценарии.

Пример использования: Тест для валидатора и тест виджета с тапом.

// Функция валидации (вынесена отдельно)
String? validateEmail(String? value) {
  if (value == null || value.isEmpty) return 'Введите email';
  final regex = RegExp(r'^[^@]+@[^@]+\.[^@]+$');
  return regex.hasMatch(value) ? null : 'Некорректный email';
}

// Тесты
void main() {
  test('Валидатор email принимает корректный адрес', () {
    expect(validateEmail('test@example.com'), isNull);
  });

  test('Валидатор email отклоняет некорректный адрес', () {
    expect(validateEmail('invalid'), isNotNull);
  });

  testWidgets('Счётчик увеличивается по нажатию', (tester) async {
    await tester.pumpWidget(MyStateful());
    expect(find.text('Счётчик: 0'), findsOneWidget);
    await tester.tap(find.text('Увеличить'));
    await tester.pump();
    expect(find.text('Счётчик: 1'), findsOneWidget);
  });
}

9. Оптимизация производительности

Промт: Проанализируй этот Flutter-код и предложи оптимизации для уменьшения перестроений: [вставить ваш код].

Зачем: Оптимизация помогает повысить плавность UI. Промт даёт рекомендации по использованию const, split в виджеты, ключей.

Пример использования: Вы вставляете свой код, AI предлагает:

  • добавлять const к неизменным виджетам;
  • выносить часто перестраиваемые части в отдельные методы с const конструкторами;
  • использовать RepaintBoundary для сложных анимаций.

Пример до/после:

// До оптимизации
@override
Widget build(BuildContext context) {
  return Column(
    children: [
      Text('Заголовок'),
      Text('Подзаголовок'),
    ],
  );
}

// После оптимизации
@override
Widget build(BuildContext context) {
  return const Column(
    children: [
      Text('Заголовок'),
      Text('Подзаголовок'),
    ],
  );
}

10. Создание темы оформления

Промт: Создай тему приложения с помощью ThemeData, включая тёмный режим, цвета и шрифты.

Зачем: Единый стиль приложения создаёт положительное впечатление у пользователей.

Пример использования: Определяем светлую и тёмную темы.

class AppTheme {
  static ThemeData get lightTheme => ThemeData(
    primarySwatch: Colors.blue,
    brightness: Brightness.light,
    appBarTheme: AppBarTheme(
      backgroundColor: Colors.blue,
      foregroundColor: Colors.white,
    ),
  );

  static ThemeData get darkTheme => ThemeData(
    primarySwatch: Colors.indigo,
    brightness: Brightness.dark,
    appBarTheme: AppBarTheme(
      backgroundColor: Colors.indigo,
      foregroundColor: Colors.white,
    ),
  );
}

// В MaterialApp
MaterialApp(
  theme: AppTheme.lightTheme,
  darkTheme: AppTheme.darkTheme,
)

Заключение

Эти 10 промтов — лишь малая часть того, что можно использовать в Flutter-разработке. Адаптируйте их, комбинируйте, пробуйте новые варианты, и вы увидите, как AI ускоряет вашу работу. Но помните: всегда проверяйте сгенерированный код и понимайте, что он делает.

Подписывайтесь на наш блог, чтобы получать новые подборки промтов и практические руководства по Flutter. Оставляйте комментарии — мы обратной связью делаем контент лучше.

← Все статьи

Комментарии

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

Cambridge Primary English (0058): учим английский по международному стандарту с нуля

1 августа 2026

Освойте графовые базы данных и Neo4j с обучением на основе ИИ на asibiont.com

1 августа 2026

Курс API Design (REST, GraphQL, gRPC): как проектировать API, которые не стыдно показать коллегам

1 августа 2026

10 промтов для оптимизации производительности кода: от профилирования до рефакторинга

1 августа 2026

Почему я создал open-source сканер AST, чтобы застраховать свой AI-сгенерированный код

1 августа 2026

9 промтов для Data Science и Pandas: анализ данных и визуализация

1 августа 2026

NVIDIA Cosmos-H-Dreams: революция в симуляции для хирургической робототехники

1 августа 2026

Сэм Альтман — не единственный, кто хочет притормозить ИИ: разбираем, почему индустрия пересматривает темпы развития

1 августа 2026

Крипторегулирование на ходу: как комплаенс-офицер покорил MiCA с помощью курса Cryptocurrency & Blockchain Regulation (SEC, FINMA, ESMA, FCA)

1 августа 2026