{
"title": "18 Prompts for Flutter: Widgets, State Management, and Animations",
"content": "## Introduction\n\nFlutter has become one of the most popular frameworks for building cross-platform mobile apps, thanks to its expressive widgets, reactive state management, and smooth animations. But even experienced developers sometimes struggle with structuring code, handling complex UI, or debugging performance issues. That‘s where well-crafted prompts come in. Whether you use them with AI assistants or as checklists for your own development process, the right prompts can save hours of trial and error.\n\nThis collection covers 18 essential prompts across three categories: widgets (basic), state management (advanced), and animations (expert). Each prompt includes a clear task, the exact prompt to use, and a concrete example result. By the end, you’ll have a practical toolkit to accelerate your Flutter projects. Let’s dive in.\n\n## Basic Prompts: Widgets and Layout\n\n### 1. Creating a Responsive Card Widget\nTask: Generate a reusable card that adapts to different screen sizes.\nPrompt: \"Write a Flutter widget called ResponsiveCard that takes a title, subtitle, and optional image URL. The card should have rounded corners, a subtle shadow, and expand its width to fill the parent container while maintaining a minimum width of 200 pixels. Use LayoutBuilder to adjust padding based on available width.\"\nExample Result:\ndart\nclass ResponsiveCard extends StatelessWidget {\n final String title;\n final String subtitle;\n final String? imageUrl;\n\n const ResponsiveCard({required this.title, required this.subtitle, this.imageUrl});\n\n @override\n Widget build(BuildContext context) {\n return LayoutBuilder(\n builder: (context, constraints) {\n double horizontalPadding = constraints.maxWidth > 400 ? 24.0 : 12.0;\n return Card(\n shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),\n elevation: 3,\n child: Padding(\n padding: EdgeInsets.symmetric(horizontal: horizontalPadding, vertical: 16),\n child: Column(\n crossAxisAlignment: CrossAxisAlignment.start,\n children: [\n if (imageUrl != null) Image.network(imageUrl!, height: 100, fit: BoxFit.cover),\n Text(title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),\n SizedBox(height: 8),\n Text(subtitle, style: TextStyle(color: Colors.grey[600])),\n ],\n ),\n ),\n );\n },\n );\n }\n}\n\n\n### 2. Building a Custom ListTile with Swipe Actions\nTask: Create a list item that reveals delete and edit buttons when swiped.\nPrompt: \"Implement a SwipeableListTile widget using Dismissible that shows a red delete background on left swipe and a blue edit background on right swipe. The tile should display a leading icon, a title, and a trailing arrow.\"\nExample Result:\ndart\nclass SwipeableListTile extends StatelessWidget {\n final String title;\n final IconData icon;\n final VoidCallback onDelete;\n final VoidCallback onEdit;\n\n SwipeableListTile({required this.title, required this.icon, required this.onDelete, required this.onEdit});\n\n @override\n Widget build(BuildContext context) {\n return Dismissible(\n key: Key(title),\n onDismissed: (direction) => direction == DismissDirection.startToEnd ? onEdit() : onDelete(),\n background: Container(color: Colors.blue, alignment: Alignment.centerLeft, child: Icon(Icons.edit, color: Colors.white)),\n secondaryBackground: Container(color: Colors.red, alignment: Alignment.centerRight, child: Icon(Icons.delete, color: Colors.white)),\n child: ListTile(leading: Icon(icon), title: Text(title), trailing: Icon(Icons.chevron_right)),\n );\n }\n}\n\n\n### 3. Form with Validation\nTask: Build a signup form with email, password, and confirm password fields, each with validation.\nPrompt: \"Create a SignupForm widget using Form and TextFormField. Validate email format, require password length >= 8, and check that passwords match. Show error messages below each field.\"\nExample Result:\ndart\nclass SignupForm extends StatefulWidget {\n @override\n _SignupFormState createState() => _SignupFormState();\n}\n\nclass _SignupFormState extends State<SignupForm> {\n final _formKey = GlobalKey<FormState>();\n final _emailController = TextEditingController();\n final _passwordController = TextEditingController();\n final _confirmController = TextEditingController();\n\n @override\n Widget build(BuildContext context) {\n return Form(\n key: _formKey,\n child: Column(\n children: [\n TextFormField(controller: _emailController, decoration: InputDecoration(labelText: 'Email'), validator: (v) => v!.contains('@') ? null : 'Invalid email'),\n TextFormField(controller: _passwordController, obscureText: true, decoration: InputDecoration(labelText: 'Password'), validator: (v) => v!.length >= 8 ? null : 'Too short'),\n TextFormField(controller: _confirmController, obscureText: true, decoration: InputDecoration(labelText: 'Confirm password'), validator: (v) => v == _passwordController.text ? null : 'Passwords do not match'),\n ElevatedButton(onPressed: () { if (_formKey.currentState!.validate()) { /* submit */ } }, child: Text('Sign up')),\n ],\n ),\n );\n }\n}\n\n\n### 4. Custom Bottom Navigation Bar with Badges\nTask: Implement a bottom navigation bar with badge notifications on specific tabs.\nPrompt: \"Write a BottomNavWithBadges widget that uses BottomNavigationBar and shows a red circle badge with a number on the second tab. Use Stack and Positioned for the badge.\"\nExample Result:\ndart\nclass BottomNavWithBadges extends StatelessWidget {\n final int currentIndex;\n final int badgeCount;\n final ValueChanged<int> onTap;\n\n BottomNavWithBadges({required this.currentIndex, required this.badgeCount, required this.onTap});\n\n @override\n Widget build(BuildContext context) {\n return BottomNavigationBar(\n currentIndex: currentIndex,\n onTap: onTap,\n items: [\n BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),\n BottomNavigationBarItem(\n icon: Stack(\n children: [\n Icon(Icons.notifications),\n if (badgeCount > 0)\n Positioned(right: 0, top: 0, child: Container(padding: EdgeInsets.all(4), decoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle), child: Text('$badgeCount', style: TextStyle(color: Colors.white, fontSize: 10)))),\n ],\n ),\n label: 'Notifications',\n ),\n BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),\n ],\n );\n }\n}\n\n\n### 5. GridView with Dynamic Items\nTask: Create a grid of product cards fetched from a list.\nPrompt: \"Generate a ProductGrid widget that takes a list of product names and prices, and displays them in a 2-column grid with GridView.builder. Each cell shows the name, price, and a placeholder image.\"\nExample Result:\ndart\nclass ProductGrid extends StatelessWidget {\n final List<Map<String, String>> products;\n\n ProductGrid({required this.products});\n\n @override\n Widget build(BuildContext context) {\n return GridView.builder(\n gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 0.8),\n itemCount: products.length,\n itemBuilder: (context, index) {\n return Card(\n child: Column(\n children: [\n Container(height: 100, color: Colors.grey[200], child: Icon(Icons.image)),\n Text(products[index]['name']!),\n Text('\$${products[index]['price']}', style: TextStyle(color: Colors.green)),\n ],\n ),\n );\n },\n );\n }\n}\n\n\n### 6. Custom Dialog with Blur Background\nTask: Show a centered alert dialog with a blurred backdrop.\nPrompt: \"Implement a BlurDialog widget that uses BackdropFilter to blur the background when the dialog is displayed. The dialog should have a title, content text, and two buttons (Cancel and Confirm).\"\nExample Result:\ndart\nvoid showBlurDialog(BuildContext context) {\n showDialog(\n context: context,\n builder: (context) => Stack(\n children: [\n BackdropFilter(filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), child: Container(color: Colors.black.withOpacity(0.3))),\n AlertDialog(title: Text('Confirm'), content: Text('Are you sure?'), actions: [TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancel')), TextButton(onPressed: () => Navigator.pop(context), child: Text('Confirm'))]),\n ],\n ),\n );\n}\n\n\n## Advanced Prompts: State Management (Bloc & Riverpod)\n\n### 7. Counter App with Bloc Pattern\nTask: Implement a counter using the Bloc pattern (flutter_bloc).\nPrompt: \"Create a CounterCubit that manages an integer state. Expose increment() and decrement() methods. Then build a CounterView that displays the count and two buttons, using BlocBuilder to rebuild on state changes.\"\nExample Result:\ndart\nclass CounterCubit extends Cubit<int> {\n CounterCubit() : super(0);\n void increment() => emit(state + 1);\n void decrement() => emit(state - 1);\n}\n\nclass CounterView extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n final cubit = context.read<CounterCubit>();\n return BlocBuilder<CounterCubit, int>(\n builder: (context, count) => Column(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n Text('$count', style: TextStyle(fontSize: 48)),\n Row(mainAxisAlignment: MainAxisAlignment.center, children: [\n FloatingActionButton(onPressed: () => cubit.decrement(), child: Icon(Icons.remove)),\n SizedBox(width: 20),\n FloatingActionButton(onPressed: () => cubit.increment(), child: Icon(Icons.add)),\n ]),\n ],\n ),\n );\n }\n}\n\n\n### 8. Fetching Data with Riverpod\nTask: Load and display a list of users from a REST API using Riverpod.\nPrompt: \"Define a userProvider using FutureProvider.family that fetches user data from https://jsonplaceholder.typicode.com/users. Then create a UserList widget that uses AsyncValue to handle loading, error, and data states.\"\nExample Result:\ndart\nfinal userProvider = FutureProvider.family<User, int>((ref, id) async {\n final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users/$id'));\n return User.fromJson(jsonDecode(response.body));\n});\n\nclass UserList extends ConsumerWidget {\n @override\n Widget build(BuildContext context, WidgetRef ref) {\n final userAsync = ref.watch(userProvider(1));\n return userAsync.when(\n loading: () => CircularProgressIndicator(),\n error: (e, _) => Text('Error: $e'),\n data: (user) => ListTile(title: Text(user.name), subtitle: Text(user.email)),\n );\n }\n}\n\n\n### 9. Theme toggling with Bloc\nTask: Switch between light and dark themes using a Bloc.\nPrompt: \"Create a ThemeCubit that toggles between ThemeData.light() and ThemeData.dark(). Use BlocProvider at the app root and BlocBuilder to rebuild MaterialApp with the selected theme.\"\nExample Result:\ndart\nclass ThemeCubit extends Cubit<ThemeData> {\n ThemeCubit() : super(ThemeData.light());\n void toggle() => emit(state == ThemeData.light() ? ThemeData.dark() : ThemeData.light());\n}\n\nvoid main() => runApp(BlocProvider(create: (_) => ThemeCubit(), child: MyApp()));\n\nclass MyApp extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return BlocBuilder<ThemeCubit, ThemeData>(\n builder: (context, theme) => MaterialApp(theme: theme, home: Scaffold(appBar: AppBar(title: Text('Theme')), body: Center(child: ElevatedButton(onPressed: () => context.read<ThemeCubit>().toggle(), child: Text('Toggle'))))),\n );\n }\n}\n\n\n### 10. Shopping Cart with Riverpod (StateNotifier)\nTask: Manage a list of cart items with add/remove functionality.\nPrompt: \"Write a CartNotifier extending StateNotifier<List<CartItem>> with methods addItem and removeItem. Each CartItem has name, price, and quantity. Expose a cartProvider and build a CartView that lists items and shows total price.\"\nExample Result:\ndart\nclass CartItem { final String name; final double price; int quantity; CartItem(this.name, this.price, this.quantity); }\n\nclass CartNotifier extends StateNotifier<List<CartItem>> {\n CartNotifier() : super([]);\n void addItem(CartItem item) => state = [...state, item];\n void removeItem(String name) => state = state.where((item) => item.name != name).toList();\n}\n\nfinal cartProvider = StateNotifierProvider<CartNotifier, List<CartItem>>((ref) => CartNotifier());\n\nclass CartView extends ConsumerWidget {\n @override\n Widget build(BuildContext context, WidgetRef ref) {\n final cart = ref.watch(cartProvider);\n double total = cart.fold(0, (sum, item) => sum + item.price * item.quantity);\n return Column(\n children: [\n Expanded(child: ListView.builder(itemCount: cart.length, itemBuilder: (_, i) => ListTile(title: Text(cart[i].name), subtitle: Text('\$${cart[i].price} x ${cart[i].quantity}')))),\n Text('Total: \$${total.toStringAsFixed(2)}', style: TextStyle(fontSize: 20)),\n ],\n );\n }\n}\n\n\n### 11. Authentication Flow with Bloc\nTask: Implement login/logout with authentication state.\nPrompt: \"Create an AuthBloc that emits AuthState (authenticated or unauthenticated). The bloc listens for LoginEvent and LogoutEvent. Use BlocListener to navigate to different screens based on state.\"\nExample Result:\ndart\nabstract class AuthState {}\nclass AuthAuthenticated extends AuthState {}\nclass AuthUnauthenticated extends AuthState {}\n\nabstract class AuthEvent {}\nclass LoginEvent extends AuthEvent {}\nclass LogoutEvent extends AuthEvent {}\n\nclass AuthBloc extends Bloc<AuthEvent, AuthState> {\n AuthBloc() : super(AuthUnauthenticated()) {\n on<LoginEvent>((event, emit) => emit(AuthAuthenticated()));\n on<LogoutEvent>((event, emit) => emit(AuthUnauthenticated()));\n }\n}\n\n// In widget tree:\nBlocListener<AuthBloc, AuthState>(\n listener: (context, state) {\n if (state is AuthAuthenticated) Navigator.pushReplacementNamed(context, '/home');\n if (state is AuthUnauthenticated) Navigator.pushReplacementNamed(context, '/login');\n },\n child: Scaffold(...),\n)\n\n\n### 12. Form State with Riverpod (AutoDispose)\nTask: Manage a complex form’s state and auto-dispose when leaving the screen.\nPrompt: \"Use AutoDisposeStateNotifierProvider to manage login form fields (email, password). The notifier should validate on submit. Show validation errors in the UI.\"\nExample Result:\ndart\nclass LoginFormNotifier extends AutoDisposeStateNotifier<LoginFormState> {\n LoginFormNotifier() : super(LoginFormState());\n void setEmail(String v) => state = state.copyWith(email: v);\n void setPassword(String v) => state = state.copyWith(password: v);\n bool validate() { /* check fields */ return state.email.contains('@'); }\n}\n\nfinal loginFormProvider = AutoDisposeStateNotifierProvider<LoginFormNotifier, LoginFormState>((ref) => LoginFormNotifier());\n\n\n## Expert Prompts: Animations\n\n### 13. Animated Container with Curves\nTask: Animate a container’s size and color on tap.\nPrompt: \"Use AnimatedContainer to toggle between a small red square and a large blue rounded rectangle when tapped. Duration: 500ms, curve: Curves.easeInOut.\"\nExample Result:\ndart\nclass AnimatedBox extends StatefulWidget {\n @override\n _AnimatedBoxState createState() => _AnimatedBoxState();\n}\n\nclass _AnimatedBoxState extends State<AnimatedBox> {\n bool _expanded = false;\n\n @override\n Widget build(BuildContext context) {\n return GestureDetector(\n onTap: () => setState(() => _expanded = !_expanded),\n child: AnimatedContainer(\n duration: Duration(milliseconds: 500),\n curve: Curves.easeInOut,\n width: _expanded ? 200 : 100,\n height: _expanded ? 200 : 100,\n decoration: BoxDecoration(color: _expanded ? Colors.blue : Colors.red, borderRadius: BorderRadius.circular(_expanded ? 20 : 0)),\n ),\n );\n }\n}\n\n\n### 14. Staggered Animation with AnimationController\nTask: Animate multiple elements sequentially.\nPrompt: \"Create a staggered animation where three boxes slide in from the left, one after another, with 200ms delay between each. Use AnimationController and Tween.\"\nExample Result:\ndart\nclass StaggeredAnimation extends StatefulWidget {\n @override\n _StaggeredAnimationState createState() => _StaggeredAnimationState();\n}\n\nclass _StaggeredAnimationState extends State<StaggeredAnimation> with SingleTickerProviderStateMixin {\n late AnimationController _controller;\n\n @override\n void initState() {\n _controller = AnimationController(vsync: this, duration: Duration(seconds: 1));\n _controller.forward();\n super.initState();\n }\n\n Widget _buildBox(double delay) {\n return SlideTransition(\n position: Tween<Offset>(begin: Offset(-1, 0), end: Offset.zero).animate(CurvedAnimation(parent: _controller, curve: Interval(delay, delay + 0.3, curve: Curves.ease))),\n child: Container(width: 100, height: 100, color: Colors.blue),\n );\n }\n\n @override\n Widget build(BuildContext context) {\n return Column(mainAxisAlignment: MainAxisAlignment.center, children: [\n _buildBox(0.0),\n _buildBox(0.3),\n _buildBox(0.6),\n ]);\n }\n}\n\n\n### 15. Hero Animation Between Screens\nTask: Transition an image from a list to a detail page.\nPrompt: \"Wrap an image in a Hero widget with the same tag on both the list item and the detail page. Navigate using Navigator.push.\"\nExample Result:\ndart\n// List page\nHero(tag: 'image_1', child: Image.network('https://picsum.photos/200', width: 100)),\n// Detail page\nHero(tag: 'image_1', child: Image.network('https://picsum.photos/800', width: double.infinity)),\n\n\n### 16. Custom Painter Animation\nTask: Draw a glowing circle that pulses.\nPrompt: \"Implement a CustomPainter that draws a circle with a radial gradient. Use an AnimationController to change the radius and opacity over time, creating a pulse effect.\"\nExample Result:\ndart\nclass PulsePainter extends CustomPainter {\n final double progress;\n PulsePainter(this.progress);\n\n @override\n void paint(Canvas canvas, Size size) {\n final paint = Paint()..shader = RadialGradient(colors: [Colors.blue.withOpacity(1 - progress), Colors.blue.withOpacity(0)]).createShader(Rect.fromCircle(center: Offset(size.width/2, size.height/2), radius: 50 * (1 + progress)));\n canvas.drawCircle(Offset(size.width/2, size.height/2), 50 * (1 + progress), paint);\n }\n\n @override\n bool shouldRepaint(covariant PulsePainter oldDelegate) => oldDelegate.progress != progress;\n}\n\n\n### 17. PageView with Animated Indicators\nTask: Create a carousel with dots that animate on page change.\nPrompt: \"Build a CarouselWithDots using PageView and a row of AnimatedContainer dots. The active dot should be larger and colored differently.\"\nExample Result:\ndart\nclass CarouselWithDots extends StatefulWidget {\n @override\n _CarouselWithDotsState createState() => _CarouselWithDotsState();\n}\n\nclass _CarouselWithDotsState extends State<CarouselWithDots> {\n int _currentPage = 0;\n final _pageController = PageController();\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n Expanded(child: PageView(controller: _pageController, onPageChanged: (i) => setState(() => _currentPage = i), children: [Container(color: Colors.red), Container(color: Colors.green), Container(color: Colors.blue)])),\n Row(mainAxisAlignment: MainAxisAlignment.center, children: List.generate(3, (i) => AnimatedContainer(duration: Duration(milliseconds: 300), margin: EdgeInsets.all(4), width: _currentPage == i ? 24 : 12, height: 12, decoration: BoxDecoration(color: _currentPage == i ? Colors.blue : Colors.grey, borderRadius: BorderRadius.circular(6)))),\n ],\n );\n }\n}\n\n\n### 18. Physics-based Spring Animation\nTask: Simulate a bouncing ball using spring physics.\nPrompt: \"Use SpringSimulation from the physics library to animate a ball’s vertical position. The ball should bounce and settle at the bottom.\"\nExample Result:\ndart\nclass BouncingBall extends StatefulWidget {\n @override\n _BouncingBallState createState() => _BouncingBallState();\n}\n\nclass _BouncingBallState extends State<BouncingBall> with SingleTickerProviderStateMixin {\n late AnimationController _controller;\n late Animation<double> _animation;\n\n @override\n void initState() {\n _controller = AnimationController(vsync: this, duration: Duration(seconds: 2));\n _animation = _controller.drive(Tween<double>(begin: 0, end: 300));\n _controller.forward();\n super.initState();\n }\n\n @override\n Widget build(BuildContext context) {\n return AnimatedBuilder(\n animation: _animation,\n builder: (context, child) => CustomPaint(painter: BallPainter(_animation.value)),\n );\n }\n}\n\nclass BallPainter extends CustomPainter {\n final double y;\n BallPainter(this.y);\n\n @override\n void paint(Canvas canvas, Size size) {\n canvas.drawCircle(Offset(size.width/2, y), 20, Paint()..color = Colors.orange);\n }\n\n @override\n bool shouldRepaint(covariant BallPainter oldDelegate) => oldDelegate.y != y;\n}\n\n\n## Conclusion\n\nThese 18 prompts cover the full spectrum of Flutter development, from basic widgets to advanced state management and complex animations. Whether you’re building a simple form or a physics-based UI, having these prompts at your fingertips will streamline your workflow and help you avoid common pitfalls. The key is to adapt each prompt to your specific use case — tweak the parameters, combine multiple patterns, and always test with real data.\n\nReady to level up your Flutter skills? Start by implementing the counter app with Bloc (prompt #7) and then experiment with the staggered animation (prompt #14). The more you practice, the more natural these patterns will become. Happy coding!",
"excerpt": "A curated collection of 18 essential Flutter prompts covering widgets, state management (Bloc & Riverpod), and animations. Each prompt includes a task, exact prompt text, and a working code example. Perfect for beginners to experts."
}
Промты для Flutter: виджеты, state management, анимации
Recent articles
AI-Powered Visual Quality Control: Integrating OpenMV Cameras with ASI Biont for Real-Time Defect Detection
20 July 2026
Adaptive Streaming Models: How to Read Equations in Programming 2026
20 July 2026
How We Ran Ornith-35B on a Laptop with 8GB VRAM and Hit 99 Tokens/s on AMD Strix Halo
20 July 2026
Talk: The Art of Braiding Algorithms — Why Vibe Coding Is the Next Frontier
20 July 2026
Edge AI Face Detection on ESP32-CAM: Integrating OV2640 with ASI Biont for Offline Security Automation
20 July 2026
Corporate Governance: How AI Training on asibiont.com Prepares a New Generation of Leaders
20 July 2026
How ASI Biont Integration with Klaviyo Increased Repeat Sales by 28% and Saved 70% of Email Marketing Time
20 July 2026
Neural Networks for Beginners: How to Master ChatGPT and Midjourney Without Code or Math
20 July 2026
Zigbee Smart Home Meets AI: A Practical Guide to Integrating Zigbee2MQTT and ZHA with ASI Biont
20 July 2026
Comments