Flutter The skill is based on Flutter framework, generated at 2026-01-31. Flutter is Google's SDK for crafting beautiful, fast user experiences for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Flutter uses Dart as its programming language and follows a widget-based architecture where everything is a widget. The framework provides hot reload for fast development cycles, a rich set of Material Design and Cupertino widgets, and excellent performance through compiled code.…

).hasMatch(value)) {\n return 'Please enter valid email';\n }\n return null;\n },\n)\n```\n\n## Password Validation\n\n```dart\nTextFormField(\n decoration: const InputDecoration(labelText: 'Password'),\n obscureText: true,\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Please enter password';\n }\n if (value.length \u003c 8) {\n return 'Password must be at least 8 characters';\n }\n if (!RegExp(r'[A-Z]').hasMatch(value)) {\n return 'Password must contain uppercase letter';\n }\n if (!RegExp(r'[0-9]').hasMatch(value)) {\n return 'Password must contain number';\n }\n return null;\n },\n)\n```\n\n## Custom Validator\n\n```dart\nString? validatePhone(String? value) {\n if (value == null || value.isEmpty) {\n return 'Please enter phone number';\n }\n if (!RegExp(r'^\\+?[1-9]\\d{1,14}

Flutter The skill is based on Flutter framework, generated at 2026-01-31. Flutter is Google's SDK for crafting beautiful, fast user experiences for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Flutter uses Dart as its programming language and follows a widget-based architecture where everything is a widget. The framework provides hot reload for fast development cycles, a rich set of Material Design and Cupertino widgets, and excellent performance through compiled code.…

).hasMatch(value)) {\n return 'Please enter valid phone number';\n }\n return null;\n}\n\n// Usage\nTextFormField(\n decoration: const InputDecoration(labelText: 'Phone'),\n validator: validatePhone,\n)\n```\n\n## FormField\n\nCustom form field with validation.\n\n```dart\nFormField\u003cString>(\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Please enter value';\n }\n return null;\n },\n builder: (field) {\n return Column(\n crossAxisAlignment: CrossAxisAlignment.start,\n children: [\n TextField(\n onChanged: field.didChange,\n decoration: InputDecoration(\n labelText: 'Custom Field',\n errorText: field.errorText,\n ),\n ),\n ],\n );\n },\n)\n```\n\n## Autovalidate Mode\n\n```dart\nForm(\n autovalidateMode: AutovalidateMode.onUserInteraction,\n child: TextFormField(\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Required';\n }\n return null;\n },\n ),\n)\n```\n\n## Form State\n\n```dart\nfinal _formKey = GlobalKey\u003cFormState>();\n\n// Validate form\nif (_formKey.currentState!.validate()) {\n // Form is valid\n}\n\n// Save form\n_formKey.currentState!.save();\n\n// Reset form\n_formKey.currentState!.reset();\n```\n\n## Multiple Fields\n\n```dart\nfinal _formKey = GlobalKey\u003cFormState>();\nfinal _emailController = TextEditingController();\nfinal _passwordController = TextEditingController();\n\nForm(\n key: _formKey,\n child: Column(\n children: [\n TextFormField(\n controller: _emailController,\n decoration: const InputDecoration(labelText: 'Email'),\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Required';\n }\n return null;\n },\n ),\n TextFormField(\n controller: _passwordController,\n decoration: const InputDecoration(labelText: 'Password'),\n obscureText: true,\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Required';\n }\n return null;\n },\n ),\n ElevatedButton(\n onPressed: () {\n if (_formKey.currentState!.validate()) {\n final email = _emailController.text;\n final password = _passwordController.text;\n // Process form\n }\n },\n child: const Text('Submit'),\n ),\n ],\n ),\n)\n```\n\n## Key Points\n\n- Use `Form` widget to wrap form fields\n- Use `GlobalKey\u003cFormState>` to access form state\n- Use `validator` function for field validation\n- Return `null` for valid values, error string for invalid\n- Use `validate()` to check form validity\n- Use `save()` to save form values\n- Use `reset()` to reset form\n- Set `autovalidateMode` for real-time validation\n- Use regex patterns for complex validation\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/form.dart\n- https://docs.flutter.dev/development/ui/widgets/material#Input%20and%20selections\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4963,"content_sha256":"c8a151577263d10c2442c61f871299984b3c866ed8205ff4c9db5479dfa25d0b"},{"filename":"references/features-hero-animations.md","content":"---\nname: features-hero-animations\ndescription: Flutter Hero animations - Hero widget, shared element transitions between routes\n---\n\n# Hero Animations\n\nHero animations create smooth transitions for widgets that move between routes.\n\n## Basic Hero\n\nCreate a hero animation by wrapping widgets with the same tag.\n\n```dart\n// First screen\nHero(\n tag: 'avatar',\n child: CircleAvatar(\n radius: 30,\n backgroundImage: NetworkImage('https://example.com/avatar.jpg'),\n ),\n)\n\n// Second screen\nHero(\n tag: 'avatar',\n child: CircleAvatar(\n radius: 100,\n backgroundImage: NetworkImage('https://example.com/avatar.jpg'),\n ),\n)\n```\n\n## Hero Properties\n\n```dart\nHero(\n tag: 'unique-tag', // Must be unique and match between screens\n child: Widget(...),\n flightShuttleBuilder: (context, animation, flightDirection, fromHeroContext, toHeroContext) {\n // Custom transition widget\n return ScaleTransition(\n scale: animation,\n child: child,\n );\n },\n placeholderBuilder: (context, size, child) {\n // Widget shown while hero is transitioning\n return Container(\n width: size.width,\n height: size.height,\n color: Colors.grey,\n );\n },\n transitionOnUserGestures: false, // Allow gesture-based transitions\n createRectTween: (begin, end) {\n // Custom tween for hero bounds\n return RectTween(begin: begin, end: end);\n },\n)\n```\n\n## Complete Example\n\n```dart\nclass FirstScreen extends StatelessWidget {\n const FirstScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(title: const Text('First Screen')),\n body: Center(\n child: GestureDetector(\n onTap: () {\n Navigator.push(\n context,\n MaterialPageRoute(builder: (context) => const SecondScreen()),\n );\n },\n child: Hero(\n tag: 'avatar',\n child: CircleAvatar(\n radius: 50,\n backgroundImage: NetworkImage('https://example.com/avatar.jpg'),\n ),\n ),\n ),\n ),\n );\n }\n}\n\nclass SecondScreen extends StatelessWidget {\n const SecondScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(title: const Text('Second Screen')),\n body: Center(\n child: Hero(\n tag: 'avatar',\n child: CircleAvatar(\n radius: 150,\n backgroundImage: NetworkImage('https://example.com/avatar.jpg'),\n ),\n ),\n ),\n );\n }\n}\n```\n\n## Custom Flight Shuttle\n\nCustomize the hero transition widget.\n\n```dart\nHero(\n tag: 'custom-hero',\n flightShuttleBuilder: (context, animation, flightDirection, fromHeroContext, toHeroContext) {\n final hero = flightDirection == HeroFlightDirection.push\n ? toHeroContext.widget\n : fromHeroContext.widget;\n \n return RotationTransition(\n turns: animation,\n child: ScaleTransition(\n scale: animation,\n child: hero,\n ),\n );\n },\n child: Container(...),\n)\n```\n\n## Multiple Heroes\n\nUse multiple heroes in the same transition.\n\n```dart\n// First screen\nColumn(\n children: [\n Hero(\n tag: 'title',\n child: Text('Title', style: TextStyle(fontSize: 24)),\n ),\n Hero(\n tag: 'image',\n child: Image.network('https://example.com/image.jpg'),\n ),\n ],\n)\n\n// Second screen\nColumn(\n children: [\n Hero(\n tag: 'title',\n child: Text('Title', style: TextStyle(fontSize: 48)),\n ),\n Hero(\n tag: 'image',\n child: Image.network('https://example.com/image.jpg'),\n ),\n ],\n)\n```\n\n## Hero with List\n\nHero animations work with ListView items.\n\n```dart\nListView.builder(\n itemBuilder: (context, index) {\n return ListTile(\n leading: Hero(\n tag: 'avatar-$index',\n child: CircleAvatar(...),\n ),\n title: Text('Item $index'),\n onTap: () {\n Navigator.push(\n context,\n MaterialPageRoute(\n builder: (context) => DetailScreen(index: index),\n ),\n );\n },\n );\n },\n)\n```\n\n## Key Points\n\n- Use `Hero` widget for shared element transitions\n- Tags must be unique and match between screens\n- Hero works automatically with Navigator transitions\n- Use `flightShuttleBuilder` for custom transition widgets\n- Use `placeholderBuilder` to show widget during transition\n- Multiple heroes can animate simultaneously\n- Hero animations work with any widget, not just images\n- Ensure hero widgets have similar visual appearance for best effect\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/heroes.dart\n- https://docs.flutter.dev/development/ui/animations/hero-animations\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4748,"content_sha256":"00f3f4b050b44353d0ea021d1a45567187ddec9e6a1fc20d25cbc96c6a85e65d"},{"filename":"references/features-http.md","content":"---\nname: features-http\ndescription: Flutter HTTP and networking - http package, API calls, JSON parsing, and network requests\n---\n\n# HTTP and Networking\n\nFlutter provides ways to make HTTP requests and handle network data.\n\n## HTTP Package\n\nAdd http package to `pubspec.yaml`.\n\n```yaml\ndependencies:\n http: ^1.1.0\n```\n\n## GET Request\n\n```dart\nimport 'package:http/http.dart' as http;\nimport 'dart:convert';\n\nFuture\u003cMap\u003cString, dynamic>> fetchData() async {\n final response = await http.get(\n Uri.parse('https://api.example.com/data'),\n );\n \n if (response.statusCode == 200) {\n return jsonDecode(response.body) as Map\u003cString, dynamic>;\n } else {\n throw Exception('Failed to load data');\n }\n}\n```\n\n## POST Request\n\n```dart\nFuture\u003cMap\u003cString, dynamic>> postData(Map\u003cString, dynamic> data) async {\n final response = await http.post(\n Uri.parse('https://api.example.com/data'),\n headers: {'Content-Type': 'application/json'},\n body: jsonEncode(data),\n );\n \n if (response.statusCode == 200 || response.statusCode == 201) {\n return jsonDecode(response.body) as Map\u003cString, dynamic>;\n } else {\n throw Exception('Failed to post data');\n }\n}\n```\n\n## Request with Headers\n\n```dart\nFuture\u003cMap\u003cString, dynamic>> fetchWithAuth() async {\n final response = await http.get(\n Uri.parse('https://api.example.com/data'),\n headers: {\n 'Authorization': 'Bearer $token',\n 'Content-Type': 'application/json',\n },\n );\n \n return jsonDecode(response.body) as Map\u003cString, dynamic>;\n}\n```\n\n## Error Handling\n\n```dart\nFuture\u003cMap\u003cString, dynamic>?> fetchDataSafely() async {\n try {\n final response = await http.get(\n Uri.parse('https://api.example.com/data'),\n ).timeout(const Duration(seconds: 5));\n \n if (response.statusCode == 200) {\n return jsonDecode(response.body) as Map\u003cString, dynamic>;\n } else {\n print('Error: ${response.statusCode}');\n return null;\n }\n } on TimeoutException {\n print('Request timeout');\n return null;\n } on SocketException {\n print('No internet connection');\n return null;\n } catch (e) {\n print('Error: $e');\n return null;\n }\n}\n```\n\n## Using with FutureBuilder\n\n```dart\nFutureBuilder\u003cMap\u003cString, dynamic>>(\n future: fetchData(),\n builder: (context, snapshot) {\n if (snapshot.connectionState == ConnectionState.waiting) {\n return const CircularProgressIndicator();\n }\n \n if (snapshot.hasError) {\n return Text('Error: ${snapshot.error}');\n }\n \n if (snapshot.hasData) {\n return Text('Data: ${snapshot.data}');\n }\n \n return const Text('No data');\n },\n)\n```\n\n## HTTP Client\n\nCreate reusable HTTP client.\n\n```dart\nimport 'package:http/http.dart' as http;\n\nclass ApiClient {\n final String baseUrl;\n final Map\u003cString, String> defaultHeaders;\n\n ApiClient({\n required this.baseUrl,\n this.defaultHeaders = const {},\n });\n\n Future\u003cMap\u003cString, dynamic>> get(String endpoint) async {\n final response = await http.get(\n Uri.parse('$baseUrl$endpoint'),\n headers: defaultHeaders,\n );\n \n return jsonDecode(response.body) as Map\u003cString, dynamic>;\n }\n\n Future\u003cMap\u003cString, dynamic>> post(String endpoint, Map\u003cString, dynamic> data) async {\n final response = await http.post(\n Uri.parse('$baseUrl$endpoint'),\n headers: {\n ...defaultHeaders,\n 'Content-Type': 'application/json',\n },\n body: jsonEncode(data),\n );\n \n return jsonDecode(response.body) as Map\u003cString, dynamic>;\n }\n}\n```\n\n## Key Points\n\n- Use `http` package for HTTP requests\n- Use `Uri.parse()` to create URIs\n- Handle status codes appropriately\n- Use `jsonEncode()` and `jsonDecode()` for JSON\n- Add headers for authentication\n- Handle errors and timeouts\n- Use `FutureBuilder` to display async data\n- Create reusable HTTP client classes\n\n\u003c!--\nSource references:\n- https://pub.dev/packages/http\n- https://docs.flutter.dev/development/data-and-backend/networking\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3956,"content_sha256":"fd5e419229131eccdfa1838d768007f70b08a6ec3bb5f17444e213dbb72b55c5"},{"filename":"references/features-implicit-animations.md","content":"---\nname: features-implicit-animations\ndescription: Flutter implicit animations - AnimatedContainer, AnimatedOpacity, AnimatedSize, and other implicit animation widgets\n---\n\n# Implicit Animations\n\nImplicit animations automatically animate property changes. They're simpler to use than explicit animations but less flexible.\n\n## AnimatedContainer\n\nAutomatically animates changes to Container properties.\n\n```dart\nclass AnimatedContainerExample extends StatefulWidget {\n const AnimatedContainerExample({super.key});\n\n @override\n State\u003cAnimatedContainerExample> createState() => _AnimatedContainerExampleState();\n}\n\nclass _AnimatedContainerExampleState extends State\u003cAnimatedContainerExample> {\n bool _expanded = false;\n\n @override\n Widget build(BuildContext context) {\n return GestureDetector(\n onTap: () {\n setState(() {\n _expanded = !_expanded;\n });\n },\n child: AnimatedContainer(\n duration: const Duration(milliseconds: 300),\n curve: Curves.easeInOut,\n width: _expanded ? 200 : 100,\n height: _expanded ? 200 : 100,\n decoration: BoxDecoration(\n color: _expanded ? Colors.blue : Colors.red,\n borderRadius: BorderRadius.circular(_expanded ? 20 : 10),\n ),\n child: Center(\n child: Text(_expanded ? 'Expanded' : 'Collapsed'),\n ),\n ),\n );\n }\n}\n```\n\n## AnimatedOpacity\n\nAnimates opacity changes.\n\n```dart\nclass AnimatedOpacityExample extends StatefulWidget {\n const AnimatedOpacityExample({super.key});\n\n @override\n State\u003cAnimatedOpacityExample> createState() => _AnimatedOpacityExampleState();\n}\n\nclass _AnimatedOpacityExampleState extends State\u003cAnimatedOpacityExample> {\n bool _visible = true;\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n AnimatedOpacity(\n opacity: _visible ? 1.0 : 0.0,\n duration: const Duration(milliseconds: 300),\n child: const FlutterLogo(size: 100),\n ),\n ElevatedButton(\n onPressed: () {\n setState(() {\n _visible = !_visible;\n });\n },\n child: Text(_visible ? 'Hide' : 'Show'),\n ),\n ],\n );\n }\n}\n```\n\n## AnimatedSize\n\nAnimates size changes.\n\n```dart\nclass AnimatedSizeExample extends StatefulWidget {\n const AnimatedSizeExample({super.key});\n\n @override\n State\u003cAnimatedSizeExample> createState() => _AnimatedSizeExampleState();\n}\n\nclass _AnimatedSizeExampleState extends State\u003cAnimatedSizeExample> {\n bool _expanded = false;\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n AnimatedSize(\n duration: const Duration(milliseconds: 300),\n curve: Curves.easeInOut,\n child: Container(\n width: _expanded ? 200 : 100,\n height: _expanded ? 200 : 100,\n color: Colors.blue,\n child: _expanded\n ? const Center(child: Text('Expanded'))\n : const Center(child: Text('Small')),\n ),\n ),\n ElevatedButton(\n onPressed: () {\n setState(() {\n _expanded = !_expanded;\n });\n },\n child: Text(_expanded ? 'Collapse' : 'Expand'),\n ),\n ],\n );\n }\n}\n```\n\n## AnimatedCrossFade\n\nCross-fades between two children.\n\n```dart\nclass AnimatedCrossFadeExample extends StatefulWidget {\n const AnimatedCrossFadeExample({super.key});\n\n @override\n State\u003cAnimatedCrossFadeExample> createState() => _AnimatedCrossFadeExampleState();\n}\n\nclass _AnimatedCrossFadeExampleState extends State\u003cAnimatedCrossFadeExample> {\n bool _showFirst = true;\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n AnimatedCrossFade(\n duration: const Duration(milliseconds: 300),\n firstChild: Container(\n width: 200,\n height: 200,\n color: Colors.red,\n child: const Center(child: Text('First')),\n ),\n secondChild: Container(\n width: 200,\n height: 200,\n color: Colors.blue,\n child: const Center(child: Text('Second')),\n ),\n crossFadeState: _showFirst\n ? CrossFadeState.showFirst\n : CrossFadeState.showSecond,\n ),\n ElevatedButton(\n onPressed: () {\n setState(() {\n _showFirst = !_showFirst;\n });\n },\n child: const Text('Toggle'),\n ),\n ],\n );\n }\n}\n```\n\n## AnimatedSwitcher\n\nSwitches between children with a transition.\n\n```dart\nclass AnimatedSwitcherExample extends StatefulWidget {\n const AnimatedSwitcherExample({super.key});\n\n @override\n State\u003cAnimatedSwitcherExample> createState() => _AnimatedSwitcherExampleState();\n}\n\nclass _AnimatedSwitcherExampleState extends State\u003cAnimatedSwitcherExample> {\n int _counter = 0;\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n AnimatedSwitcher(\n duration: const Duration(milliseconds: 300),\n transitionBuilder: (child, animation) {\n return ScaleTransition(\n scale: animation,\n child: child,\n );\n },\n child: Text(\n '$_counter',\n key: ValueKey(_counter),\n style: const TextStyle(fontSize: 48),\n ),\n ),\n ElevatedButton(\n onPressed: () {\n setState(() {\n _counter++;\n });\n },\n child: const Text('Increment'),\n ),\n ],\n );\n }\n}\n```\n\n## AnimatedPositioned\n\nAnimates position changes within a Stack.\n\n```dart\nclass AnimatedPositionedExample extends StatefulWidget {\n const AnimatedPositionedExample({super.key});\n\n @override\n State\u003cAnimatedPositionedExample> createState() => _AnimatedPositionedExampleState();\n}\n\nclass _AnimatedPositionedExampleState extends State\u003cAnimatedPositionedExample> {\n bool _moved = false;\n\n @override\n Widget build(BuildContext context) {\n return Stack(\n children: [\n AnimatedPositioned(\n duration: const Duration(milliseconds: 300),\n left: _moved ? 200 : 0,\n top: _moved ? 200 : 0,\n child: Container(\n width: 100,\n height: 100,\n color: Colors.blue,\n ),\n ),\n Positioned(\n bottom: 20,\n left: 20,\n child: ElevatedButton(\n onPressed: () {\n setState(() {\n _moved = !_moved;\n });\n },\n child: const Text('Move'),\n ),\n ),\n ],\n );\n }\n}\n```\n\n## Animation Curves\n\nUse curves to control animation timing.\n\n```dart\nAnimatedContainer(\n duration: const Duration(milliseconds: 300),\n curve: Curves.easeInOut, // Common curves: linear, easeIn, easeOut, easeInOut, bounce, elastic\n // ... properties\n)\n```\n\n## Key Points\n\n- Implicit animations automatically animate property changes\n- Use `AnimatedContainer` for animating container properties\n- Use `AnimatedOpacity` for fade in/out effects\n- Use `AnimatedSize` for size changes\n- Use `AnimatedCrossFade` to transition between two widgets\n- Use `AnimatedSwitcher` to switch between children\n- Use `AnimatedPositioned` for position animations in Stack\n- Specify `duration` and `curve` for timing control\n- Implicit animations are simpler but less flexible than explicit animations\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/implicit_animations.dart\n- https://docs.flutter.dev/development/ui/animations/implicit-animations\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7712,"content_sha256":"fba031e8e2d71651407a2792081872b6471781f47e8d72b0f15c4d2a0b6686bd"},{"filename":"references/features-inherited-widget.md","content":"---\nname: features-inherited-widget\ndescription: Flutter InheritedWidget - sharing data down the widget tree, theme access, and InheritedWidget patterns\n---\n\n# InheritedWidget\n\n`InheritedWidget` efficiently shares data down the widget tree.\n\n## Basic InheritedWidget\n\n```dart\nclass CounterInherited extends InheritedWidget {\n final int count;\n final VoidCallback increment;\n\n const CounterInherited({\n super.key,\n required this.count,\n required this.increment,\n required super.child,\n });\n\n static CounterInherited? of(BuildContext context) {\n return context.dependOnInheritedWidgetOfExactType\u003cCounterInherited>();\n }\n\n @override\n bool updateShouldNotify(CounterInherited oldWidget) {\n return count != oldWidget.count;\n }\n}\n```\n\n## Using InheritedWidget\n\n```dart\nCounterInherited(\n count: _count,\n increment: _increment,\n child: MyApp(),\n)\n\n// Access in descendant\nclass CounterDisplay extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n final counter = CounterInherited.of(context);\n return Text('Count: ${counter?.count ?? 0}');\n }\n}\n```\n\n## updateShouldNotify\n\nControl when descendants rebuild.\n\n```dart\n@override\nbool updateShouldNotify(CounterInherited oldWidget) {\n // Only rebuild if count changed\n return count != oldWidget.count;\n}\n```\n\n## dependOnInheritedWidgetOfExactType\n\nRegister dependency and rebuild when widget changes.\n\n```dart\nstatic CounterInherited? of(BuildContext context) {\n return context.dependOnInheritedWidgetOfExactType\u003cCounterInherited>();\n}\n```\n\n## getElementForInheritedWidgetOfExactType\n\nAccess without registering dependency.\n\n```dart\nstatic CounterInherited? of(BuildContext context) {\n final element = context.getElementForInheritedWidgetOfExactType\u003cCounterInherited>();\n return element?.widget as CounterInherited?;\n}\n```\n\n## Complete Example\n\n```dart\nclass ThemeInherited extends InheritedWidget {\n final ThemeData theme;\n final VoidCallback toggleTheme;\n\n const ThemeInherited({\n super.key,\n required this.theme,\n required this.toggleTheme,\n required super.child,\n });\n\n static ThemeInherited? of(BuildContext context) {\n return context.dependOnInheritedWidgetOfExactType\u003cThemeInherited>();\n }\n\n @override\n bool updateShouldNotify(ThemeInherited oldWidget) {\n return theme != oldWidget.theme;\n }\n}\n\n// Usage\nThemeInherited(\n theme: _theme,\n toggleTheme: _toggleTheme,\n child: MaterialApp(...),\n)\n\n// Access\nfinal theme = ThemeInherited.of(context)?.theme;\n```\n\n## Key Points\n\n- Use `InheritedWidget` to share data down the tree\n- Implement `updateShouldNotify()` to control rebuilds\n- Use `dependOnInheritedWidgetOfExactType()` to register dependency\n- Use `getElementForInheritedWidgetOfExactType()` to access without dependency\n- More efficient than passing data through constructors\n- Used by Theme, MediaQuery, Localizations\n- Only rebuilds descendants when data changes\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/framework.dart\n- https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple#inheritedwidget\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3127,"content_sha256":"77f5d1bf9680af2ecbde7c8c39d147c42387b5c09f05e582616c85a9ececcd84"},{"filename":"references/features-keys.md","content":"---\nname: features-keys\ndescription: Flutter keys - ValueKey, ObjectKey, GlobalKey, UniqueKey, and when to use keys\n---\n\n# Keys\n\nKeys help Flutter identify which widgets correspond to which state objects.\n\n## When to Use Keys\n\nUse keys when widgets are moved around in the tree or when you need to preserve state.\n\n```dart\n// Without key - state is lost when list order changes\nListView(\n children: items.map((item) => StatefulWidget()).toList(),\n)\n\n// With key - state is preserved\nListView(\n children: items.map((item) => \n StatefulWidget(key: ValueKey(item.id))\n ).toList(),\n)\n```\n\n## ValueKey\n\nUse when widget identity is based on a value.\n\n```dart\nListView(\n children: items.map((item) => \n ListTile(\n key: ValueKey(item.id),\n title: Text(item.name),\n )\n ).toList(),\n)\n```\n\n## ObjectKey\n\nUse when widget identity is based on object identity.\n\n```dart\nListView(\n children: items.map((item) => \n ListTile(\n key: ObjectKey(item),\n title: Text(item.name),\n )\n ).toList(),\n)\n```\n\n## UniqueKey\n\nGenerate a unique key each time (use sparingly).\n\n```dart\n// Creates new key on every build - not recommended\nWidget build(BuildContext context) {\n return Widget(key: UniqueKey());\n}\n\n// Better - create once in initState\n@override\nvoid initState() {\n super.initState();\n _key = UniqueKey();\n}\n```\n\n## GlobalKey\n\nUniquely identify widgets across the entire app.\n\n```dart\nfinal _formKey = GlobalKey\u003cFormState>();\n\nForm(\n key: _formKey,\n child: TextFormField(),\n)\n\n// Access form state from anywhere\n_formKey.currentState?.validate();\n```\n\n## GlobalKey for State Access\n\n```dart\nfinal _counterKey = GlobalKey\u003c_CounterWidgetState>();\n\nCounterWidget(key: _counterKey)\n\n// Access state\n_counterKey.currentState?.increment();\n```\n\n## Key in AnimatedSwitcher\n\nUse keys to force widget recreation.\n\n```dart\nAnimatedSwitcher(\n duration: Duration(milliseconds: 300),\n child: Text(\n '$_counter',\n key: ValueKey(_counter), // Force recreation on change\n ),\n)\n```\n\n## Key Best Practices\n\n```dart\n// ✅ Good - use ValueKey for list items\nListView.builder(\n itemBuilder: (context, index) => ListTile(\n key: ValueKey(items[index].id),\n title: Text(items[index].name),\n ),\n)\n\n// ✅ Good - use GlobalKey for form access\nfinal _formKey = GlobalKey\u003cFormState>();\n\n// ❌ Bad - creating UniqueKey on every build\nWidget build(BuildContext context) {\n return Widget(key: UniqueKey());\n}\n\n// ✅ Good - create key once\nfinal _key = UniqueKey();\n```\n\n## Key Points\n\n- Use `ValueKey` for list items with stable IDs\n- Use `ObjectKey` when identity is based on object reference\n- Use `UniqueKey` sparingly, create once in initState\n- Use `GlobalKey` to access state from outside\n- Keys help preserve state when widgets move\n- Keys help Flutter identify widgets efficiently\n- Don't create keys unnecessarily\n- Use keys in lists, AnimatedSwitcher, and when accessing state\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/framework.dart\n- https://docs.flutter.dev/development/ui/widgets-intro#keys\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3088,"content_sha256":"f30f26ac6933e26e8d172962364c2310b4716e946c100b48d9b0295b5a64e21b"},{"filename":"references/features-lifecycle.md","content":"---\nname: features-lifecycle\ndescription: Flutter widget lifecycle - initState, dispose, didChangeDependencies, and lifecycle management\n---\n\n# Widget Lifecycle\n\nUnderstanding widget lifecycle helps manage resources and state properly.\n\n## StatefulWidget Lifecycle\n\n```dart\nclass MyWidget extends StatefulWidget {\n const MyWidget({super.key});\n\n @override\n State\u003cMyWidget> createState() => _MyWidgetState();\n}\n\nclass _MyWidgetState extends State\u003cMyWidget> {\n @override\n void initState() {\n super.initState();\n // Called once when widget is created\n // Initialize state, subscribe to streams, etc.\n }\n\n @override\n void didChangeDependencies() {\n super.didChangeDependencies();\n // Called when InheritedWidgets change\n // Called after initState\n }\n\n @override\n Widget build(BuildContext context) {\n // Called every time widget needs to rebuild\n return Container();\n }\n\n @override\n void didUpdateWidget(MyWidget oldWidget) {\n super.didUpdateWidget(oldWidget);\n // Called when widget configuration changes\n // Compare oldWidget with widget\n }\n\n @override\n void deactivate() {\n // Called when widget is removed from tree\n // Widget may be reinserted elsewhere\n super.deactivate();\n }\n\n @override\n void dispose() {\n // Called when widget is permanently removed\n // Clean up resources, cancel subscriptions\n super.dispose();\n }\n}\n```\n\n## initState\n\nInitialize state and resources.\n\n```dart\n@override\nvoid initState() {\n super.initState();\n \n // Initialize state\n _counter = 0;\n \n // Subscribe to streams\n _subscription = stream.listen((data) {\n setState(() {\n _data = data;\n });\n });\n \n // Start animations\n _controller.forward();\n}\n```\n\n## dispose\n\nClean up resources.\n\n```dart\n@override\nvoid dispose() {\n // Cancel subscriptions\n _subscription?.cancel();\n \n // Dispose controllers\n _controller.dispose();\n _focusNode.dispose();\n \n // Close streams\n _streamController.close();\n \n super.dispose();\n}\n```\n\n## didChangeDependencies\n\nReact to InheritedWidget changes.\n\n```dart\n@override\nvoid didChangeDependencies() {\n super.didChangeDependencies();\n \n // Access InheritedWidget\n final theme = Theme.of(context);\n final locale = Localizations.localeOf(context);\n \n // React to changes\n if (theme != _previousTheme) {\n // Theme changed\n }\n}\n```\n\n## didUpdateWidget\n\nHandle widget configuration changes.\n\n```dart\n@override\nvoid didUpdateWidget(MyWidget oldWidget) {\n super.didUpdateWidget(oldWidget);\n \n // Compare old and new configuration\n if (widget.data != oldWidget.data) {\n // Data changed, update state\n _loadData();\n }\n}\n```\n\n## App Lifecycle\n\nListen to app lifecycle changes.\n\n```dart\nclass AppLifecycleWidget extends StatefulWidget {\n const AppLifecycleWidget({super.key});\n\n @override\n State\u003cAppLifecycleWidget> createState() => _AppLifecycleWidgetState();\n}\n\nclass _AppLifecycleWidgetState extends State\u003cAppLifecycleWidget>\n with WidgetsBindingObserver {\n @override\n void initState() {\n super.initState();\n WidgetsBinding.instance.addObserver(this);\n }\n\n @override\n void dispose() {\n WidgetsBinding.instance.removeObserver(this);\n super.dispose();\n }\n\n @override\n void didChangeAppLifecycleState(AppLifecycleState state) {\n switch (state) {\n case AppLifecycleState.resumed:\n // App resumed\n break;\n case AppLifecycleState.paused:\n // App paused\n break;\n case AppLifecycleState.inactive:\n // App inactive\n break;\n case AppLifecycleState.detached:\n // App detached\n break;\n case AppLifecycleState.hidden:\n // App hidden\n break;\n }\n }\n}\n```\n\n## Key Points\n\n- `initState()` - Called once, initialize state\n- `didChangeDependencies()` - Called when InheritedWidgets change\n- `build()` - Called every rebuild\n- `didUpdateWidget()` - Called when configuration changes\n- `deactivate()` - Called when removed from tree\n- `dispose()` - Called when permanently removed\n- Always call `super` methods\n- Clean up resources in `dispose()`\n- Use `WidgetsBindingObserver` for app lifecycle\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/framework.dart\n- https://docs.flutter.dev/development/ui/widgets-intro#stateful-and-stateless-widgets\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4340,"content_sha256":"e658ece60a7584ed7a808ceab01fa45a6c596f26074a8cbf8fcb2dd6d3c8e02a"},{"filename":"references/features-material-3.md","content":"---\nname: features-material-3\ndescription: Material 3 design system - Material 3 components, color schemes, and design tokens\n---\n\n# Material 3\n\nMaterial 3 (Material You) is the latest Material Design system with dynamic color and updated components.\n\n## Enable Material 3\n\nEnable Material 3 in your app.\n\n```dart\nMaterialApp(\n theme: ThemeData(\n useMaterial3: true,\n colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),\n ),\n home: const HomeScreen(),\n)\n```\n\n## ColorScheme\n\nMaterial 3 uses dynamic color schemes.\n\n```dart\n// Generate from seed color\nColorScheme.fromSeed(\n seedColor: Colors.blue,\n brightness: Brightness.light,\n)\n\n// Custom color scheme\nColorScheme(\n brightness: Brightness.light,\n primary: Colors.blue,\n onPrimary: Colors.white,\n secondary: Colors.purple,\n onSecondary: Colors.white,\n error: Colors.red,\n onError: Colors.white,\n surface: Colors.white,\n onSurface: Colors.black,\n surfaceVariant: Colors.grey[100]!,\n onSurfaceVariant: Colors.grey[800]!,\n)\n```\n\n## Material 3 Components\n\n### FilledButton\n\nFilled button style (Material 3).\n\n```dart\nFilledButton(\n onPressed: () {},\n child: const Text('Filled Button'),\n)\n\nFilledButton.icon(\n onPressed: () {},\n icon: const Icon(Icons.add),\n label: const Text('Add'),\n)\n```\n\n### FilledTonalButton\n\nTonal filled button.\n\n```dart\nFilledTonalButton(\n onPressed: () {},\n child: const Text('Tonal Button'),\n)\n```\n\n### SegmentedButton\n\nSegmented button group.\n\n```dart\nSegmentedButton\u003cString>(\n segments: const [\n ButtonSegment(value: 'list', label: Text('List')),\n ButtonSegment(value: 'grid', label: Text('Grid')),\n ],\n selected: {'list'},\n onSelectionChanged: (Set\u003cString> newSelection) {\n setState(() {\n selected = newSelection;\n });\n },\n)\n```\n\n### NavigationBar\n\nBottom navigation bar (Material 3).\n\n```dart\nNavigationBar(\n selectedIndex: _currentIndex,\n onTap: (index) {\n setState(() {\n _currentIndex = index;\n });\n },\n destinations: const [\n NavigationDestination(icon: Icon(Icons.home), label: 'Home'),\n NavigationDestination(icon: Icon(Icons.search), label: 'Search'),\n NavigationDestination(icon: Icon(Icons.person), label: 'Profile'),\n ],\n)\n```\n\n### NavigationRail\n\nSide navigation rail.\n\n```dart\nNavigationRail(\n selectedIndex: _currentIndex,\n onDestinationSelected: (index) {\n setState(() {\n _currentIndex = index;\n });\n },\n labelType: NavigationRailLabelType.all,\n destinations: const [\n NavigationRailDestination(\n icon: Icon(Icons.home),\n label: Text('Home'),\n ),\n NavigationRailDestination(\n icon: Icon(Icons.search),\n label: Text('Search'),\n ),\n ],\n)\n```\n\n### SearchBar\n\nSearch bar component.\n\n```dart\nSearchBar(\n hintText: 'Search...',\n onChanged: (value) {\n // Handle search\n },\n leading: const Icon(Icons.search),\n trailing: [\n IconButton(\n icon: const Icon(Icons.clear),\n onPressed: () {},\n ),\n ],\n)\n```\n\n## Material 3 Theming\n\n```dart\nThemeData(\n useMaterial3: true,\n colorScheme: ColorScheme.fromSeed(\n seedColor: Colors.blue,\n brightness: Brightness.light,\n ),\n // Material 3 specific themes\n navigationBarTheme: NavigationBarThemeData(...),\n navigationRailTheme: NavigationRailThemeData(...),\n searchBarTheme: SearchBarThemeData(...),\n)\n```\n\n## Key Points\n\n- Set `useMaterial3: true` to enable Material 3\n- Use `ColorScheme.fromSeed()` for dynamic colors\n- Material 3 introduces new components like `FilledButton`, `NavigationBar`, `SearchBar`\n- Material 3 uses updated design tokens and spacing\n- Components adapt to color scheme automatically\n- Material 3 provides better accessibility and customization\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/material\n- https://m3.material.io/\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3796,"content_sha256":"06ae44742f8ae92316383610915bf45e204765d7fb8e169562ba732ce45ec2f9"},{"filename":"references/features-material-app.md","content":"---\nname: features-material-app\ndescription: MaterialApp widget, Theme, ThemeData, and Material Design theming\n---\n\n# Material App\n\n`MaterialApp` is the main widget for Material Design applications. It provides theme, navigation, and other app-wide features.\n\n## MaterialApp\n\nBasic Material app setup.\n\n```dart\nMaterialApp(\n title: 'My App',\n theme: ThemeData(\n colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),\n useMaterial3: true,\n ),\n home: const HomeScreen(),\n)\n```\n\n## Theme Configuration\n\n### Basic Theme\n\n```dart\nMaterialApp(\n theme: ThemeData(\n // Color scheme\n colorScheme: ColorScheme.fromSeed(\n seedColor: Colors.blue,\n brightness: Brightness.light,\n ),\n \n // Typography\n textTheme: TextTheme(\n headlineLarge: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),\n bodyLarge: TextStyle(fontSize: 16),\n ),\n \n // Component themes\n appBarTheme: const AppBarTheme(\n backgroundColor: Colors.blue,\n foregroundColor: Colors.white,\n ),\n \n // Use Material 3\n useMaterial3: true,\n ),\n home: const HomeScreen(),\n)\n```\n\n### Dark Theme\n\n```dart\nMaterialApp(\n theme: ThemeData.light(),\n darkTheme: ThemeData.dark(),\n themeMode: ThemeMode.system, // system, light, dark\n home: const HomeScreen(),\n)\n```\n\n## ColorScheme\n\nMaterial 3 color scheme.\n\n```dart\nColorScheme.fromSeed(\n seedColor: Colors.blue,\n brightness: Brightness.light,\n)\n\n// Access colors\nTheme.of(context).colorScheme.primary\nTheme.of(context).colorScheme.secondary\nTheme.of(context).colorScheme.surface\nTheme.of(context).colorScheme.error\nTheme.of(context).colorScheme.onPrimary\n```\n\n## ThemeData Properties\n\n```dart\nThemeData(\n // Colors\n primaryColor: Colors.blue,\n scaffoldBackgroundColor: Colors.white,\n \n // Typography\n fontFamily: 'Roboto',\n textTheme: TextTheme(...),\n \n // Component themes\n appBarTheme: AppBarTheme(...),\n buttonTheme: ButtonThemeData(...),\n cardTheme: CardTheme(...),\n inputDecorationTheme: InputDecorationTheme(...),\n \n // Material 3\n useMaterial3: true,\n \n // Other\n visualDensity: VisualDensity.adaptivePlatformDensity,\n)\n```\n\n## Using Theme\n\nAccess theme in widgets.\n\n```dart\nclass ThemedWidget extends StatelessWidget {\n const ThemedWidget({super.key});\n\n @override\n Widget build(BuildContext context) {\n final theme = Theme.of(context);\n final colorScheme = theme.colorScheme;\n \n return Container(\n color: colorScheme.primary,\n child: Text(\n 'Hello',\n style: theme.textTheme.headlineMedium?.copyWith(\n color: colorScheme.onPrimary,\n ),\n ),\n );\n }\n}\n```\n\n## Theme Extension\n\nCreate custom theme extensions.\n\n```dart\nclass AppColors extends ThemeExtension\u003cAppColors> {\n final Color customColor;\n\n AppColors({required this.customColor});\n\n @override\n AppColors copyWith({Color? customColor}) {\n return AppColors(customColor: customColor ?? this.customColor);\n }\n\n @override\n AppColors lerp(ThemeExtension\u003cAppColors>? other, double t) {\n if (other is! AppColors) return this;\n return AppColors(\n customColor: Color.lerp(customColor, other.customColor, t)!,\n );\n }\n}\n\n// Usage\nMaterialApp(\n theme: ThemeData(\n extensions: [\n AppColors(customColor: Colors.purple),\n ],\n ),\n)\n\n// Access\nfinal appColors = Theme.of(context).extension\u003cAppColors>();\nfinal customColor = appColors?.customColor;\n```\n\n## MaterialApp Properties\n\n```dart\nMaterialApp(\n title: 'App Title',\n theme: ThemeData.light(),\n darkTheme: ThemeData.dark(),\n themeMode: ThemeMode.system,\n debugShowCheckedModeBanner: false,\n home: HomeScreen(),\n initialRoute: '/',\n routes: {\n '/': (context) => HomeScreen(),\n '/detail': (context) => DetailScreen(),\n },\n onGenerateRoute: (settings) {\n // Custom route generation\n },\n navigatorObservers: [MyNavigatorObserver()],\n builder: (context, child) {\n // Wrap app with additional widgets\n return MediaQuery(\n data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),\n child: child!,\n );\n },\n)\n```\n\n## Key Points\n\n- Use `MaterialApp` as the root widget for Material Design apps\n- Configure `theme` and `darkTheme` for light/dark modes\n- Use `ColorScheme.fromSeed()` for Material 3 color schemes\n- Access theme via `Theme.of(context)`\n- Use `ThemeExtension` for custom theme properties\n- Set `useMaterial3: true` for Material 3 design\n- Configure component themes in `ThemeData`\n- Use `themeMode` to control light/dark theme switching\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/material/app.dart\n- https://docs.flutter.dev/development/ui/widgets/material\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4668,"content_sha256":"dabfff4c6a411bf6bf294ef36038c4f22e42e6116d4e2e2252bb2d87dcc9806d"},{"filename":"references/features-material-components.md","content":"---\nname: features-material-components\ndescription: Material Design components - AppBar, Scaffold, Drawer, BottomNavigationBar, and other Material widgets\n---\n\n# Material Components\n\nFlutter provides a comprehensive set of Material Design components.\n\n## Scaffold\n\nBasic Material Design visual structure.\n\n```dart\nScaffold(\n appBar: AppBar(\n title: const Text('Title'),\n ),\n body: const Center(\n child: Text('Body'),\n ),\n floatingActionButton: FloatingActionButton(\n onPressed: () {},\n child: const Icon(Icons.add),\n ),\n drawer: Drawer(...),\n bottomNavigationBar: BottomNavigationBar(...),\n)\n```\n\n## AppBar\n\nTop app bar.\n\n```dart\nAppBar(\n title: const Text('Title'),\n leading: IconButton(\n icon: const Icon(Icons.menu),\n onPressed: () {},\n ),\n actions: [\n IconButton(\n icon: const Icon(Icons.search),\n onPressed: () {},\n ),\n IconButton(\n icon: const Icon(Icons.more_vert),\n onPressed: () {},\n ),\n ],\n backgroundColor: Colors.blue,\n foregroundColor: Colors.white,\n elevation: 4,\n flexibleSpace: Container(...), // Custom background\n)\n```\n\n## Drawer\n\nNavigation drawer.\n\n```dart\nDrawer(\n child: ListView(\n padding: EdgeInsets.zero,\n children: [\n const DrawerHeader(\n decoration: BoxDecoration(color: Colors.blue),\n child: Text('Header'),\n ),\n ListTile(\n leading: const Icon(Icons.home),\n title: const Text('Home'),\n onTap: () {\n Navigator.pop(context);\n },\n ),\n ListTile(\n leading: const Icon(Icons.settings),\n title: const Text('Settings'),\n onTap: () {\n Navigator.pop(context);\n },\n ),\n ],\n ),\n)\n```\n\n## BottomNavigationBar\n\nBottom navigation bar.\n\n```dart\nint _currentIndex = 0;\n\nBottomNavigationBar(\n currentIndex: _currentIndex,\n onTap: (index) {\n setState(() {\n _currentIndex = index;\n });\n },\n items: const [\n BottomNavigationBarItem(\n icon: Icon(Icons.home),\n label: 'Home',\n ),\n BottomNavigationBarItem(\n icon: Icon(Icons.search),\n label: 'Search',\n ),\n BottomNavigationBarItem(\n icon: Icon(Icons.person),\n label: 'Profile',\n ),\n ],\n type: BottomNavigationBarType.fixed, // fixed, shifting\n)\n```\n\n## Card\n\nMaterial Design card.\n\n```dart\nCard(\n elevation: 4,\n shape: RoundedRectangleBorder(\n borderRadius: BorderRadius.circular(12),\n ),\n child: Padding(\n padding: const EdgeInsets.all(16),\n child: Column(\n children: [\n const Text('Title'),\n const Text('Content'),\n ],\n ),\n ),\n)\n```\n\n## Dialog\n\nModal dialog.\n\n```dart\nshowDialog(\n context: context,\n builder: (context) => AlertDialog(\n title: const Text('Title'),\n content: const Text('Content'),\n actions: [\n TextButton(\n onPressed: () => Navigator.pop(context),\n child: const Text('Cancel'),\n ),\n ElevatedButton(\n onPressed: () => Navigator.pop(context),\n child: const Text('OK'),\n ),\n ],\n ),\n)\n```\n\n## SnackBar\n\nTemporary message at bottom of screen.\n\n```dart\nScaffoldMessenger.of(context).showSnackBar(\n SnackBar(\n content: const Text('Message'),\n action: SnackBarAction(\n label: 'Action',\n onPressed: () {},\n ),\n duration: const Duration(seconds: 3),\n behavior: SnackBarBehavior.floating,\n ),\n)\n```\n\n## BottomSheet\n\nBottom sheet modal.\n\n```dart\nshowModalBottomSheet(\n context: context,\n builder: (context) => Container(\n padding: const EdgeInsets.all(16),\n child: Column(\n mainAxisSize: MainAxisSize.min,\n children: [\n ListTile(\n leading: const Icon(Icons.share),\n title: const Text('Share'),\n onTap: () {},\n ),\n ListTile(\n leading: const Icon(Icons.delete),\n title: const Text('Delete'),\n onTap: () {},\n ),\n ],\n ),\n ),\n)\n```\n\n## Key Points\n\n- Use `Scaffold` as the main structure for Material apps\n- `AppBar` provides top navigation and actions\n- `Drawer` provides side navigation\n- `BottomNavigationBar` provides bottom navigation\n- Use `Card` for elevated content containers\n- Use `showDialog` for modal dialogs\n- Use `SnackBar` for temporary messages\n- Use `showModalBottomSheet` for bottom sheets\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/material\n- https://docs.flutter.dev/development/ui/widgets/material\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4433,"content_sha256":"fecc10b56520baa6c658a4d301652e12e55d89674e978b53544c5c12124cb684"},{"filename":"references/features-named-routes.md","content":"---\nname: features-named-routes\ndescription: Flutter named routes - route configuration, onGenerateRoute, and route arguments\n---\n\n# Named Routes\n\nNamed routes provide a cleaner way to navigate using route names instead of route builders.\n\n## Basic Setup\n\nDefine routes in MaterialApp.\n\n```dart\nMaterialApp(\n initialRoute: '/',\n routes: {\n '/': (context) => const HomeScreen(),\n '/detail': (context) => const DetailScreen(),\n '/settings': (context) => const SettingsScreen(),\n },\n)\n```\n\n## Navigation with Named Routes\n\n```dart\n// Navigate to named route\nNavigator.pushNamed(context, '/detail');\n\n// Navigate with arguments\nNavigator.pushNamed(\n context,\n '/detail',\n arguments: {'id': 123, 'name': 'Item'},\n);\n\n// Navigate and remove current route\nNavigator.pushReplacementNamed(context, '/home');\n\n// Navigate and remove all previous routes\nNavigator.pushNamedAndRemoveUntil(\n context,\n '/login',\n (route) => false, // Remove all routes\n);\n```\n\n## Accessing Route Arguments\n\n```dart\nclass DetailScreen extends StatelessWidget {\n const DetailScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n final args = ModalRoute.of(context)?.settings.arguments as Map\u003cString, dynamic>?;\n final id = args?['id'] ?? 0;\n final name = args?['name'] ?? '';\n\n return Scaffold(\n appBar: AppBar(title: Text('Detail: $name')),\n body: Center(\n child: Text('ID: $id'),\n ),\n );\n }\n}\n```\n\n## onGenerateRoute\n\nGenerate routes dynamically with custom logic.\n\n```dart\nMaterialApp(\n initialRoute: '/',\n onGenerateRoute: (settings) {\n switch (settings.name) {\n case '/':\n return MaterialPageRoute(builder: (_) => const HomeScreen());\n \n case '/detail':\n final args = settings.arguments as Map\u003cString, dynamic>?;\n return MaterialPageRoute(\n builder: (_) => DetailScreen(\n id: args?['id'] ?? 0,\n name: args?['name'] ?? '',\n ),\n );\n \n case '/user':\n final userId = settings.arguments as String;\n return MaterialPageRoute(\n builder: (_) => UserScreen(userId: userId),\n );\n \n default:\n return MaterialPageRoute(\n builder: (_) => const NotFoundScreen(),\n );\n }\n },\n)\n```\n\n## Route Settings\n\nPass route settings for better route management.\n\n```dart\nNavigator.pushNamed(\n context,\n '/detail',\n arguments: {'id': 123},\n);\n\n// Access settings\nfinal route = ModalRoute.of(context);\nfinal routeName = route?.settings.name;\nfinal arguments = route?.settings.arguments;\n```\n\n## Route Generation with Type Safety\n\nUse typed route arguments for better type safety.\n\n```dart\nclass RouteArguments {\n final int id;\n final String name;\n\n RouteArguments({required this.id, required this.name});\n}\n\n// Navigation\nNavigator.pushNamed(\n context,\n '/detail',\n arguments: RouteArguments(id: 123, name: 'Item'),\n);\n\n// Access\nfinal args = ModalRoute.of(context)?.settings.arguments as RouteArguments?;\n```\n\n## Unknown Route Handling\n\nHandle unknown routes.\n\n```dart\nMaterialApp(\n onGenerateRoute: (settings) {\n // Handle known routes\n if (settings.name == '/') {\n return MaterialPageRoute(builder: (_) => const HomeScreen());\n }\n \n // Handle unknown routes\n return MaterialPageRoute(\n builder: (_) => Scaffold(\n appBar: AppBar(title: const Text('Not Found')),\n body: Center(\n child: Text('Route \"${settings.name}\" not found'),\n ),\n ),\n );\n },\n onUnknownRoute: (settings) {\n // Fallback for unknown routes\n return MaterialPageRoute(\n builder: (_) => const NotFoundScreen(),\n );\n },\n)\n```\n\n## Route Guards\n\nImplement route guards with onGenerateRoute.\n\n```dart\nMaterialApp(\n onGenerateRoute: (settings) {\n // Check authentication\n if (settings.name == '/profile' && !isAuthenticated) {\n return MaterialPageRoute(builder: (_) => const LoginScreen());\n }\n \n // Handle route\n switch (settings.name) {\n case '/':\n return MaterialPageRoute(builder: (_) => const HomeScreen());\n case '/profile':\n return MaterialPageRoute(builder: (_) => const ProfileScreen());\n default:\n return MaterialPageRoute(builder: (_) => const NotFoundScreen());\n }\n },\n)\n```\n\n## Key Points\n\n- Use `routes` map for simple static routes\n- Use `onGenerateRoute` for dynamic route generation\n- Pass arguments via `Navigator.pushNamed(arguments: ...)`\n- Access arguments via `ModalRoute.of(context)?.settings.arguments`\n- Use `onUnknownRoute` as fallback for unknown routes\n- Implement route guards in `onGenerateRoute`\n- Use typed arguments classes for better type safety\n- Named routes make navigation more maintainable\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/navigator.dart\n- https://docs.flutter.dev/development/ui/navigation\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4910,"content_sha256":"4a9eaae17c3eb913038b1dc9027952d83e3bbf75a2419766c17253b0391c2056"},{"filename":"references/features-navigation.md","content":"---\nname: features-navigation\ndescription: Flutter navigation - Navigator.push, Navigator.pop, routes, and navigation patterns\n---\n\n# Navigation\n\nFlutter provides the `Navigator` widget for managing a stack of routes. Navigation allows users to move between different screens in your app.\n\n## Basic Navigation\n\n### Push a Route\n\n```dart\n// Navigate to a new screen\nNavigator.of(context).push(\n MaterialPageRoute(\n builder: (context) => const NextScreen(),\n ),\n);\n\n// With result\nfinal result = await Navigator.of(context).push(\n MaterialPageRoute(\n builder: (context) => const NextScreen(),\n ),\n);\n```\n\n### Pop a Route\n\n```dart\n// Pop current route\nNavigator.of(context).pop();\n\n// Pop with result\nNavigator.of(context).pop('result data');\n```\n\n### Complete Example\n\n```dart\nclass HomeScreen extends StatelessWidget {\n const HomeScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(title: const Text('Home')),\n body: Center(\n child: ElevatedButton(\n onPressed: () async {\n final result = await Navigator.of(context).push(\n MaterialPageRoute(\n builder: (context) => const DetailScreen(),\n ),\n );\n \n if (result != null) {\n ScaffoldMessenger.of(context).showSnackBar(\n SnackBar(content: Text('Result: $result')),\n );\n }\n },\n child: const Text('Go to Detail'),\n ),\n ),\n );\n }\n}\n\nclass DetailScreen extends StatelessWidget {\n const DetailScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(title: const Text('Detail')),\n body: Center(\n child: ElevatedButton(\n onPressed: () {\n Navigator.of(context).pop('Data from detail');\n },\n child: const Text('Go Back'),\n ),\n ),\n );\n }\n}\n```\n\n## Navigation Methods\n\n### pushReplacement\n\nReplace the current route with a new one.\n\n```dart\nNavigator.of(context).pushReplacement(\n MaterialPageRoute(builder: (context) => const NewScreen()),\n);\n```\n\n### pushAndRemoveUntil\n\nPush a new route and remove all previous routes until a condition is met.\n\n```dart\n// Navigate to home and remove all previous routes\nNavigator.of(context).pushAndRemoveUntil(\n MaterialPageRoute(builder: (context) => const HomeScreen()),\n (route) => false, // Remove all routes\n);\n\n// Navigate to login and remove all routes except the first one\nNavigator.of(context).pushAndRemoveUntil(\n MaterialPageRoute(builder: (context) => const LoginScreen()),\n (route) => route.isFirst, // Keep only the first route\n);\n```\n\n### popUntil\n\nPop routes until a condition is met.\n\n```dart\n// Pop until reaching home screen\nNavigator.of(context).popUntil((route) => route.settings.name == '/home');\n```\n\n## Route Types\n\n### MaterialPageRoute\n\nStandard Material Design page transition.\n\n```dart\nNavigator.of(context).push(\n MaterialPageRoute(\n builder: (context) => const NextScreen(),\n settings: const RouteSettings(\n name: '/detail',\n arguments: {'id': 123},\n ),\n ),\n);\n```\n\n### CupertinoPageRoute\n\niOS-style page transition.\n\n```dart\nNavigator.of(context).push(\n CupertinoPageRoute(\n builder: (context) => const NextScreen(),\n ),\n);\n```\n\n### PageRouteBuilder\n\nCustom page transition.\n\n```dart\nNavigator.of(context).push(\n PageRouteBuilder(\n pageBuilder: (context, animation, secondaryAnimation) => const NextScreen(),\n transitionsBuilder: (context, animation, secondaryAnimation, child) {\n return FadeTransition(\n opacity: animation,\n child: child,\n );\n },\n transitionDuration: const Duration(milliseconds: 300),\n ),\n);\n```\n\n## Accessing Route Arguments\n\n```dart\nclass DetailScreen extends StatelessWidget {\n const DetailScreen({super.key});\n\n @override\n Widget build(BuildContext context) {\n final args = ModalRoute.of(context)?.settings.arguments as Map\u003cString, dynamic>?;\n final id = args?['id'] ?? 0;\n \n return Scaffold(\n appBar: AppBar(title: Text('Detail $id')),\n body: Center(\n child: Text('ID: $id'),\n ),\n );\n }\n}\n```\n\n## Navigation State\n\n### Check if Can Pop\n\n```dart\nif (Navigator.of(context).canPop()) {\n Navigator.of(context).pop();\n} else {\n // Handle case where there's nothing to pop\n}\n```\n\n### Get Current Route\n\n```dart\nfinal route = ModalRoute.of(context);\nfinal routeName = route?.settings.name;\nfinal arguments = route?.settings.arguments;\n```\n\n## Key Points\n\n- Use `Navigator.push()` to navigate forward\n- Use `Navigator.pop()` to go back\n- Pass data back using `pop(result)`\n- Use `pushReplacement()` to replace current route\n- Use `pushAndRemoveUntil()` for login/logout flows\n- Access route arguments via `ModalRoute.of(context)?.settings.arguments`\n- Check `canPop()` before popping to avoid errors\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/navigator.dart\n- https://docs.flutter.dev/development/ui/navigation\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5099,"content_sha256":"b7531d03ce4316e03386805ab5b5804a47bb3b1bcdeefc40ff43adc59c3a17e3"},{"filename":"references/features-platform-channels.md","content":"---\nname: features-platform-channels\ndescription: Flutter platform channels - MethodChannel, EventChannel, and communication with native code\n---\n\n# Platform Channels\n\nPlatform channels allow Flutter to communicate with platform-specific code (Android/iOS).\n\n## MethodChannel\n\nCall platform methods from Flutter.\n\n### Flutter Side\n\n```dart\nimport 'package:flutter/services.dart';\n\nclass PlatformService {\n static const platform = MethodChannel('com.example/app');\n\n Future\u003cString> getPlatformVersion() async {\n try {\n final String version = await platform.invokeMethod('getPlatformVersion');\n return version;\n } on PlatformException catch (e) {\n return \"Failed to get version: '${e.message}'.\";\n }\n }\n\n Future\u003cvoid> showNativeDialog() async {\n try {\n await platform.invokeMethod('showDialog', {'message': 'Hello from Flutter'});\n } on PlatformException catch (e) {\n print(\"Error: ${e.message}\");\n }\n }\n}\n```\n\n### Android Side (Kotlin)\n\n```kotlin\nimport io.flutter.embedding.android.FlutterActivity\nimport io.flutter.embedding.engine.FlutterEngine\nimport io.flutter.plugin.common.MethodChannel\n\nclass MainActivity: FlutterActivity() {\n private val CHANNEL = \"com.example/app\"\n\n override fun configureFlutterEngine(flutterEngine: FlutterEngine) {\n super.configureFlutterEngine(flutterEngine)\n MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->\n when (call.method) {\n \"getPlatformVersion\" -> {\n result.success(android.os.Build.VERSION.RELEASE)\n }\n \"showDialog\" -> {\n val message = call.argument\u003cString>(\"message\")\n // Show dialog\n result.success(null)\n }\n else -> {\n result.notImplemented()\n }\n }\n }\n }\n}\n```\n\n### iOS Side (Swift)\n\n```swift\nimport Flutter\nimport UIKit\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n override func application(\n _ application: UIApplication,\n didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n ) -> Bool {\n let controller : FlutterViewController = window?.rootViewController as! FlutterViewController\n let channel = FlutterMethodChannel(name: \"com.example/app\",\n binaryMessenger: controller.binaryMessenger)\n channel.setMethodCallHandler({\n (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in\n if call.method == \"getPlatformVersion\" {\n result(\"iOS \" + UIDevice.current.systemVersion)\n } else if call.method == \"showDialog\" {\n let args = call.arguments as? [String: Any]\n let message = args?[\"message\"] as? String\n // Show dialog\n result(nil)\n } else {\n result(FlutterMethodNotImplemented)\n }\n })\n return super.application(application, didFinishLaunchingWithOptions: launchOptions)\n }\n}\n```\n\n## EventChannel\n\nStream events from platform to Flutter.\n\n### Flutter Side\n\n```dart\nimport 'package:flutter/services.dart';\n\nclass EventChannelService {\n static const eventChannel = EventChannel('com.example/events');\n\n Stream\u003cString> getBatteryLevel() {\n return eventChannel.receiveBroadcastStream().map((dynamic event) => event.toString());\n }\n}\n\n// Usage\nStreamBuilder\u003cString>(\n stream: EventChannelService().getBatteryLevel(),\n builder: (context, snapshot) {\n if (snapshot.hasData) {\n return Text('Battery: ${snapshot.data}');\n }\n return CircularProgressIndicator();\n },\n)\n```\n\n### Android Side\n\n```kotlin\nimport io.flutter.plugin.common.EventChannel\n\nEventChannel(flutterEngine.dartExecutor.binaryMessenger, \"com.example/events\")\n .setStreamHandler(object : EventChannel.StreamHandler {\n override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {\n // Start sending events\n events?.success(\"Event data\")\n }\n\n override fun onCancel(arguments: Any?) {\n // Stop sending events\n }\n })\n```\n\n## BasicMessageChannel\n\nTwo-way communication with platform.\n\n```dart\nimport 'package:flutter/services.dart';\n\nfinal messageChannel = BasicMessageChannel\u003cString>(\n 'com.example/messages',\n StringCodec(),\n);\n\n// Send message\nawait messageChannel.send('Hello from Flutter');\n\n// Set handler\nmessageChannel.setMessageHandler((message) async {\n return 'Response from Flutter';\n});\n```\n\n## Key Points\n\n- Use `MethodChannel` for one-time method calls\n- Use `EventChannel` for streaming events from platform\n- Use `BasicMessageChannel` for two-way communication\n- Channel names must match between Flutter and platform code\n- Handle `PlatformException` for error cases\n- Use `result.notImplemented()` for unsupported methods\n- Platform channels are asynchronous\n- Use proper codecs for complex data types\n\n\u003c!--\nSource references:\n- https://docs.flutter.dev/platform-integration/platform-channels\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/services/platform_channel.dart\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5153,"content_sha256":"e2f1cff14aed13bc5230e2e95761b38e53ef435bf091a955243e8eab97d2b732"},{"filename":"references/features-platform-views.md","content":"---\nname: features-platform-views\ndescription: Flutter platform views - AndroidView, UiKitView, and embedding native views\n---\n\n# Platform Views\n\nPlatform views allow embedding native Android/iOS views in Flutter.\n\n## AndroidView\n\nEmbed Android views in Flutter (Android).\n\n```dart\nimport 'dart:io';\n\nif (Platform.isAndroid) {\n AndroidView(\n viewType: 'android-view',\n layoutDirection: TextDirection.ltr,\n creationParams: {\n 'text': 'Hello from Flutter',\n },\n creationParamsCodec: const StandardMessageCodec(),\n onPlatformViewCreated: (int id) {\n // View created\n },\n ),\n}\n```\n\n### Android Setup\n\n```kotlin\nimport io.flutter.plugin.platform.PlatformView\nimport io.flutter.plugin.platform.PlatformViewFactory\nimport io.flutter.plugin.common.StandardMessageCodec\nimport android.view.View\nimport android.widget.TextView\n\nclass NativeView(context: android.content.Context, id: Int, creationParams: Any?): PlatformView {\n private val textView: TextView = TextView(context)\n \n init {\n val params = creationParams as Map\u003cString, Any>?\n textView.text = params?.get(\"text\") as? String ?: \"Default\"\n }\n \n override fun getView(): View = textView\n \n override fun dispose() {}\n}\n\nclass NativeViewFactory: PlatformViewFactory(StandardMessageCodec.INSTANCE) {\n override fun create(context: android.content.Context, viewId: Int, args: Any?): PlatformView {\n return NativeView(context, viewId, args)\n }\n}\n\n// Register in MainActivity\nflutterEngine.platformViewsController.registry.registerViewFactory(\n \"android-view\",\n NativeViewFactory()\n)\n```\n\n## UiKitView\n\nEmbed iOS views in Flutter (iOS).\n\n```dart\nimport 'dart:io';\n\nif (Platform.isIOS) {\n UiKitView(\n viewType: 'ios-view',\n creationParams: {\n 'text': 'Hello from Flutter',\n },\n creationParamsCodec: const StandardMessageCodec(),\n onPlatformViewCreated: (int id) {\n // View created\n },\n ),\n}\n```\n\n### iOS Setup\n\n```swift\nimport Flutter\nimport UIKit\n\nclass NativeViewFactory: NSObject, FlutterPlatformViewFactory {\n func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {\n return NativeView(frame: frame, arguments: args)\n }\n}\n\nclass NativeView: NSObject, FlutterPlatformView {\n private var _view: UIView\n \n init(frame: CGRect, arguments args: Any?) {\n _view = UIView()\n super.init()\n \n let params = args as? [String: Any]\n let label = UILabel()\n label.text = params?[\"text\"] as? String ?? \"Default\"\n label.frame = frame\n _view.addSubview(label)\n }\n \n func view() -> UIView {\n return _view\n }\n}\n\n// Register in AppDelegate\nlet factory = NativeViewFactory()\nregistrar.registerViewFactory(\"ios-view\", factory: factory)\n```\n\n## Hybrid Composition\n\nUse hybrid composition for better performance (Android).\n\n```dart\nAndroidView(\n viewType: 'android-view',\n hybridComposition: true, // Enable hybrid composition\n creationParams: {...},\n creationParamsCodec: const StandardMessageCodec(),\n)\n```\n\n## Key Points\n\n- Use `AndroidView` for Android native views\n- Use `UiKitView` for iOS native views\n- Platform views require platform-specific setup\n- Use `creationParams` to pass data to native views\n- Handle `onPlatformViewCreated` for view initialization\n- Use hybrid composition on Android for better performance\n- Platform views have performance considerations\n- Test on both platforms when using platform views\n\n\u003c!--\nSource references:\n- https://docs.flutter.dev/platform-integration/platform-views\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/platform_view.dart\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3713,"content_sha256":"962fc72642599bac70bed68e1dc050e49ae0d3bd5666704a694c484300d0880e"},{"filename":"references/features-pop-scope.md","content":"---\nname: features-pop-scope\ndescription: Flutter PopScope - handle back button and navigation pop events\n---\n\n# PopScope\n\n`PopScope` (formerly `WillPopScope`) handles back button and navigation pop events.\n\n## Basic Usage\n\n```dart\nPopScope(\n canPop: false, // Prevent popping\n onPopInvoked: (didPop) {\n if (!didPop) {\n // Handle back button press\n showDialog(...);\n }\n },\n child: Scaffold(...),\n)\n```\n\n## Prevent Pop\n\n```dart\nPopScope(\n canPop: false,\n onPopInvoked: (didPop) {\n if (!didPop) {\n // Show confirmation dialog\n showDialog(\n context: context,\n builder: (context) => AlertDialog(\n title: Text('Exit?'),\n content: Text('Are you sure?'),\n actions: [\n TextButton(\n onPressed: () => Navigator.pop(context),\n child: Text('Cancel'),\n ),\n ElevatedButton(\n onPressed: () {\n Navigator.pop(context);\n Navigator.pop(context); // Pop this route\n },\n child: Text('Exit'),\n ),\n ],\n ),\n );\n }\n },\n child: Scaffold(...),\n)\n```\n\n## Conditional Pop\n\n```dart\nPopScope(\n canPop: _isFormDirty ? false : true,\n onPopInvoked: (didPop) {\n if (!didPop && _isFormDirty) {\n // Show unsaved changes dialog\n showDialog(...);\n }\n },\n child: Form(...),\n)\n```\n\n## Save on Pop\n\n```dart\nPopScope(\n canPop: false,\n onPopInvoked: (didPop) async {\n if (!didPop) {\n // Save data before popping\n await saveData();\n if (mounted) {\n Navigator.pop(context);\n }\n }\n },\n child: Scaffold(...),\n)\n```\n\n## Key Points\n\n- Use `PopScope` to handle back button\n- Set `canPop: false` to prevent automatic pop\n- Use `onPopInvoked` to handle pop events\n- Check `didPop` to see if pop occurred\n- Use for unsaved changes warnings\n- Use for confirmation dialogs\n- Save data before popping if needed\n- Replaced `WillPopScope` in newer Flutter versions\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/pop_scope.dart\n- https://api.flutter.dev/flutter/widgets/PopScope-class.html\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2190,"content_sha256":"7537cfba4bcfb2e14a29906af0f74f2907d68b5ba8b25c84aa8d85dc2ede1475"},{"filename":"references/features-responsive.md","content":"---\nname: features-responsive\ndescription: Flutter responsive design - MediaQuery, LayoutBuilder, responsive layouts, and screen adaptation\n---\n\n# Responsive Design\n\nCreate layouts that adapt to different screen sizes and orientations.\n\n## MediaQuery\n\nAccess device information and screen size.\n\n```dart\nclass ResponsiveWidget extends StatelessWidget {\n const ResponsiveWidget({super.key});\n\n @override\n Widget build(BuildContext context) {\n final mediaQuery = MediaQuery.of(context);\n final screenWidth = mediaQuery.size.width;\n final screenHeight = mediaQuery.size.height;\n final orientation = mediaQuery.orientation;\n final padding = mediaQuery.padding;\n final devicePixelRatio = mediaQuery.devicePixelRatio;\n \n return Container(\n width: screenWidth * 0.8,\n height: screenHeight * 0.5,\n padding: EdgeInsets.only(top: padding.top),\n );\n }\n}\n```\n\n## LayoutBuilder\n\nBuild widgets based on available constraints.\n\n```dart\nLayoutBuilder(\n builder: (context, constraints) {\n if (constraints.maxWidth > 600) {\n return WideLayout();\n } else {\n return NarrowLayout();\n }\n },\n)\n```\n\n## Responsive Breakpoints\n\n```dart\nclass ResponsiveLayout extends StatelessWidget {\n const ResponsiveLayout({super.key});\n\n @override\n Widget build(BuildContext context) {\n final width = MediaQuery.of(context).size.width;\n \n if (width > 1200) {\n return DesktopLayout();\n } else if (width > 600) {\n return TabletLayout();\n } else {\n return MobileLayout();\n }\n }\n}\n```\n\n## Orientation Builder\n\nBuild widgets based on orientation.\n\n```dart\nOrientationBuilder(\n builder: (context, orientation) {\n if (orientation == Orientation.portrait) {\n return PortraitLayout();\n } else {\n return LandscapeLayout();\n }\n },\n)\n```\n\n## Responsive Grid\n\n```dart\nclass ResponsiveGrid extends StatelessWidget {\n const ResponsiveGrid({super.key});\n\n int _getCrossAxisCount(BuildContext context) {\n final width = MediaQuery.of(context).size.width;\n if (width > 1200) return 4;\n if (width > 600) return 3;\n return 2;\n }\n\n @override\n Widget build(BuildContext context) {\n return GridView.builder(\n gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(\n crossAxisCount: _getCrossAxisCount(context),\n crossAxisSpacing: 10,\n mainAxisSpacing: 10,\n ),\n itemBuilder: (context, index) => Container(color: Colors.blue),\n );\n }\n}\n```\n\n## Safe Area\n\nRespect device safe areas.\n\n```dart\nSafeArea(\n child: Column(\n children: [\n Text('Content'),\n ],\n ),\n)\n```\n\n## Key Points\n\n- Use `MediaQuery` to access screen information\n- Use `LayoutBuilder` for constraint-based layouts\n- Define breakpoints for responsive design\n- Use `OrientationBuilder` for orientation changes\n- Use `SafeArea` to respect device safe areas\n- Test on different screen sizes\n- Consider tablet and desktop layouts\n- Use flexible layouts that adapt to constraints\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/media_query.dart\n- https://docs.flutter.dev/development/ui/layout/responsive\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3158,"content_sha256":"c8d019bbfe7a0f5230471467b26c36563eae6e363b559655327bfd41bf619708"},{"filename":"references/features-router.md","content":"---\nname: features-router\ndescription: Flutter Router API - declarative routing, RouterDelegate, and route configuration\n---\n\n# Router API\n\nFlutter's Router API provides declarative routing for navigation.\n\n## Router Widget\n\nUse Router widget for declarative routing.\n\n```dart\nMaterialApp.router(\n routerConfig: _router,\n title: 'My App',\n)\n\nfinal _router = GoRouter(\n routes: [\n GoRoute(\n path: '/',\n builder: (context, state) => const HomeScreen(),\n ),\n GoRoute(\n path: '/detail/:id',\n builder: (context, state) {\n final id = state.pathParameters['id']!;\n return DetailScreen(id: id);\n },\n ),\n ],\n);\n```\n\n## GoRouter (go_router package)\n\nPopular declarative routing package.\n\n```dart\nimport 'package:go_router/go_router.dart';\n\nfinal router = GoRouter(\n initialLocation: '/',\n routes: [\n GoRoute(\n path: '/',\n builder: (context, state) => const HomeScreen(),\n ),\n GoRoute(\n path: '/detail/:id',\n builder: (context, state) {\n final id = state.pathParameters['id']!;\n return DetailScreen(id: int.parse(id));\n },\n ),\n GoRoute(\n path: '/settings',\n builder: (context, state) => const SettingsScreen(),\n routes: [\n GoRoute(\n path: 'profile',\n builder: (context, state) => const ProfileScreen(),\n ),\n ],\n ),\n ],\n errorBuilder: (context, state) => const NotFoundScreen(),\n);\n\n// Usage\nMaterialApp.router(\n routerConfig: router,\n)\n```\n\n## Navigation with GoRouter\n\n```dart\n// Navigate\ncontext.go('/detail/123');\n\n// Push (add to stack)\ncontext.push('/detail/123');\n\n// Pop\ncontext.pop();\n\n// Replace\ncontext.go('/home', extra: {'data': 'value'});\n\n// Access parameters\nfinal id = GoRouterState.of(context).pathParameters['id'];\nfinal query = GoRouterState.of(context).uri.queryParameters['search'];\n```\n\n## Route Guards\n\nImplement route guards with GoRouter.\n\n```dart\nfinal router = GoRouter(\n redirect: (context, state) {\n final isLoggedIn = authService.isAuthenticated;\n final isLoginRoute = state.matchedLocation == '/login';\n \n if (!isLoggedIn && !isLoginRoute) {\n return '/login';\n }\n \n if (isLoggedIn && isLoginRoute) {\n return '/';\n }\n \n return null; // No redirect\n },\n routes: [...],\n);\n```\n\n## Route Configuration\n\n```dart\nGoRoute(\n path: '/detail/:id',\n name: 'detail', // Named route\n builder: (context, state) {\n final id = state.pathParameters['id']!;\n return DetailScreen(id: id);\n },\n redirect: (context, state) {\n // Redirect logic\n return null;\n },\n)\n```\n\n## Key Points\n\n- Use `Router` widget for declarative routing\n- Use `GoRouter` package for easier route management\n- Define routes declaratively\n- Use path parameters for dynamic routes\n- Use query parameters for optional data\n- Implement route guards with `redirect`\n- Use `context.go()` for navigation\n- Use `context.push()` to add to navigation stack\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/router.dart\n- https://pub.dev/packages/go_router\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3109,"content_sha256":"a58d5db9c0b1517ab12c157a1e4f72880010e91409c39ce685d2c8af8c642118"},{"filename":"references/features-scroll-controller.md","content":"---\nname: features-scroll-controller\ndescription: Flutter ScrollController - programmatic scroll control, scroll listeners, and scroll position management\n---\n\n# ScrollController\n\n`ScrollController` provides programmatic control over scrollable widgets.\n\n## Basic Usage\n\n```dart\nclass ScrollExample extends StatefulWidget {\n const ScrollExample({super.key});\n\n @override\n State\u003cScrollExample> createState() => _ScrollExampleState();\n}\n\nclass _ScrollExampleState extends State\u003cScrollExample> {\n final ScrollController _controller = ScrollController();\n\n @override\n void dispose() {\n _controller.dispose();\n super.dispose();\n }\n\n @override\n Widget build(BuildContext context) {\n return ListView(\n controller: _controller,\n children: [\n // List items\n ],\n );\n }\n}\n```\n\n## Scroll to Position\n\n```dart\n// Jump to position\n_controller.jumpTo(500);\n\n// Animate to position\n_controller.animateTo(\n 500,\n duration: Duration(milliseconds: 300),\n curve: Curves.easeInOut,\n);\n```\n\n## Scroll Listeners\n\n```dart\n@override\nvoid initState() {\n super.initState();\n _controller.addListener(() {\n print('Scroll position: ${_controller.offset}');\n \n // Load more when near bottom\n if (_controller.position.pixels >= \n _controller.position.maxScrollExtent - 200) {\n loadMore();\n }\n });\n}\n```\n\n## Scroll Position\n\n```dart\n// Get scroll position\nfinal offset = _controller.offset;\n\n// Get max scroll extent\nfinal maxScroll = _controller.position.maxScrollExtent;\n\n// Check if at top\nfinal isAtTop = _controller.position.pixels == 0;\n\n// Check if at bottom\nfinal isAtBottom = _controller.position.pixels >= \n _controller.position.maxScrollExtent;\n```\n\n## Scroll to Top/Bottom\n\n```dart\n// Scroll to top\n_controller.animateTo(\n 0,\n duration: Duration(milliseconds: 300),\n curve: Curves.easeOut,\n);\n\n// Scroll to bottom\n_controller.animateTo(\n _controller.position.maxScrollExtent,\n duration: Duration(milliseconds: 300),\n curve: Curves.easeOut,\n);\n```\n\n## Initial Scroll Position\n\n```dart\nScrollController(\n initialScrollOffset: 500, // Start at position 500\n keepScrollOffset: true, // Persist scroll position\n)\n```\n\n## Multiple Controllers\n\n```dart\nfinal _listController = ScrollController();\nfinal _gridController = ScrollController();\n\n// Sync scrolling\n_listController.addListener(() {\n _gridController.jumpTo(_listController.offset);\n});\n```\n\n## Key Points\n\n- Use `ScrollController` to control scroll position\n- Always dispose controllers to prevent leaks\n- Use `jumpTo()` for instant scrolling\n- Use `animateTo()` for animated scrolling\n- Listen to scroll changes with `addListener()`\n- Access scroll position via `offset`\n- Check scroll extent with `maxScrollExtent`\n- Use `initialScrollOffset` to start at specific position\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/scroll_controller.dart\n- https://api.flutter.dev/flutter/widgets/ScrollController-class.html\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2998,"content_sha256":"562e530898e0112739dff04258849b72ddd7cded083dbda30bd908ef6c8d8160"},{"filename":"references/features-slivers.md","content":"---\nname: features-slivers\ndescription: Flutter Sliver widgets - CustomScrollView, SliverList, SliverGrid, and advanced scrolling effects\n---\n\n# Sliver Widgets\n\nSliver widgets provide advanced scrolling effects and custom scroll behaviors.\n\n## CustomScrollView\n\nCreate custom scroll effects with slivers.\n\n```dart\nCustomScrollView(\n slivers: [\n SliverAppBar(\n expandedHeight: 200,\n floating: false,\n pinned: true,\n flexibleSpace: FlexibleSpaceBar(\n title: Text('Title'),\n background: Image.network('url'),\n ),\n ),\n SliverList(\n delegate: SliverChildBuilderDelegate(\n (context, index) {\n return ListTile(title: Text('Item $index'));\n },\n childCount: 100,\n ),\n ),\n ],\n)\n```\n\n## SliverAppBar\n\nApp bar that responds to scrolling.\n\n```dart\nSliverAppBar(\n expandedHeight: 200,\n floating: true, // Appears when scrolling up\n pinned: true, // Stays at top when scrolling\n snap: true, // Snaps when floating\n flexibleSpace: FlexibleSpaceBar(\n title: Text('Title'),\n background: Image.network('url'),\n ),\n)\n```\n\n## SliverList\n\nList of widgets in a sliver.\n\n```dart\nSliverList(\n delegate: SliverChildBuilderDelegate(\n (context, index) {\n return ListTile(title: Text('Item $index'));\n },\n childCount: 100,\n ),\n)\n\n// With separator\nSliverList(\n delegate: SliverChildBuilderDelegate(\n (context, index) {\n return ListTile(title: Text('Item $index'));\n },\n childCount: 100,\n ),\n)\n```\n\n## SliverGrid\n\nGrid of widgets in a sliver.\n\n```dart\nSliverGrid(\n gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(\n crossAxisCount: 2,\n crossAxisSpacing: 10,\n mainAxisSpacing: 10,\n ),\n delegate: SliverChildBuilderDelegate(\n (context, index) {\n return Container(color: Colors.blue);\n },\n childCount: 20,\n ),\n)\n```\n\n## SliverPadding\n\nAdd padding to slivers.\n\n```dart\nSliverPadding(\n padding: const EdgeInsets.all(16),\n sliver: SliverList(...),\n)\n```\n\n## SliverToBoxAdapter\n\nConvert regular widget to sliver.\n\n```dart\nSliverToBoxAdapter(\n child: Container(\n height: 100,\n color: Colors.blue,\n child: Center(child: Text('Header')),\n ),\n)\n```\n\n## SliverPersistentHeader\n\nPersistent header that changes size.\n\n```dart\nSliverPersistentHeader(\n pinned: true,\n delegate: _SliverHeaderDelegate(\n minHeight: 60,\n maxHeight: 200,\n ),\n)\n```\n\n## Complete Example\n\n```dart\nCustomScrollView(\n slivers: [\n SliverAppBar(\n expandedHeight: 200,\n pinned: true,\n flexibleSpace: FlexibleSpaceBar(\n title: Text('Title'),\n background: Image.network('url'),\n ),\n ),\n SliverToBoxAdapter(\n child: Container(\n padding: EdgeInsets.all(16),\n child: Text('Header content'),\n ),\n ),\n SliverList(\n delegate: SliverChildBuilderDelegate(\n (context, index) {\n return ListTile(title: Text('Item $index'));\n },\n childCount: 100,\n ),\n ),\n ],\n)\n```\n\n## Key Points\n\n- Use `CustomScrollView` for custom scroll effects\n- Use `SliverAppBar` for app bars that respond to scrolling\n- Use `SliverList` for lists in slivers\n- Use `SliverGrid` for grids in slivers\n- Use `SliverPadding` to add padding\n- Use `SliverToBoxAdapter` to convert widgets to slivers\n- Slivers provide advanced scrolling effects\n- Combine multiple slivers for complex layouts\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/sliver.dart\n- https://docs.flutter.dev/development/ui/advanced/slivers\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3568,"content_sha256":"d6787dbc86b69ac194dcadf6897bac162b07e903332d3a8f0d9a5e34d730c306"},{"filename":"references/layout-container.md","content":"---\nname: layout-container\ndescription: Flutter Container widget, BoxDecoration, padding, margin, and container styling\n---\n\n# Container Widget\n\n`Container` combines common painting, positioning, and sizing widgets into a single widget.\n\n## Basic Container\n\n```dart\nContainer(\n width: 100,\n height: 100,\n color: Colors.blue,\n child: Text('Hello'),\n)\n```\n\n## Container Properties\n\n```dart\nContainer(\n // Sizing\n width: 200,\n height: 200,\n constraints: BoxConstraints(\n minWidth: 100,\n maxWidth: 300,\n minHeight: 100,\n maxHeight: 300,\n ),\n \n // Positioning\n alignment: Alignment.center,\n margin: EdgeInsets.all(16),\n padding: EdgeInsets.all(16),\n \n // Decoration\n decoration: BoxDecoration(\n color: Colors.blue,\n borderRadius: BorderRadius.circular(8),\n ),\n \n // Foreground decoration\n foregroundDecoration: BoxDecoration(...),\n \n // Transform\n transform: Matrix4.rotationZ(0.1),\n \n // Child\n child: Text('Content'),\n)\n```\n\n## BoxDecoration\n\nDecorate container with colors, borders, shadows, etc.\n\n```dart\nBoxDecoration(\n // Color\n color: Colors.blue,\n \n // Border\n border: Border.all(\n color: Colors.black,\n width: 2,\n ),\n \n // Border radius\n borderRadius: BorderRadius.circular(8),\n // Or\n borderRadius: BorderRadius.only(\n topLeft: Radius.circular(8),\n topRight: Radius.circular(8),\n ),\n \n // Box shadow\n boxShadow: [\n BoxShadow(\n color: Colors.black.withOpacity(0.2),\n blurRadius: 4,\n offset: Offset(0, 2),\n spreadRadius: 1,\n ),\n ],\n \n // Gradient\n gradient: LinearGradient(\n begin: Alignment.topLeft,\n end: Alignment.bottomRight,\n colors: [Colors.blue, Colors.purple],\n ),\n \n // Shape\n shape: BoxShape.rectangle, // rectangle, circle\n)\n```\n\n## Padding\n\nAdd padding around child.\n\n```dart\nContainer(\n padding: EdgeInsets.all(16), // All sides\n child: Text('Padded'),\n)\n\n// Specific sides\nContainer(\n padding: EdgeInsets.only(\n top: 10,\n left: 20,\n right: 20,\n bottom: 10,\n ),\n child: Text('Padded'),\n)\n\n// Symmetric padding\nContainer(\n padding: EdgeInsets.symmetric(\n horizontal: 20, // left and right\n vertical: 10, // top and bottom\n ),\n child: Text('Padded'),\n)\n\n// Or use Padding widget\nPadding(\n padding: EdgeInsets.all(16),\n child: Text('Padded'),\n)\n```\n\n## Margin\n\nAdd margin around container.\n\n```dart\nContainer(\n margin: EdgeInsets.all(16),\n child: Container(color: Colors.blue),\n)\n\n// Specific sides\nContainer(\n margin: EdgeInsets.only(\n top: 10,\n left: 20,\n ),\n child: Container(color: Colors.blue),\n)\n\n// Or use Margin widget (if using a package)\n```\n\n## Alignment\n\nAlign child within container.\n\n```dart\nContainer(\n width: 200,\n height: 200,\n alignment: Alignment.center,\n child: Text('Centered'),\n)\n\n// Common alignments\nalignment: Alignment.topLeft\nalignment: Alignment.topCenter\nalignment: Alignment.topRight\nalignment: Alignment.centerLeft\nalignment: Alignment.center\nalignment: Alignment.centerRight\nalignment: Alignment.bottomLeft\nalignment: Alignment.bottomCenter\nalignment: Alignment.bottomRight\n\n// Custom alignment\nalignment: Alignment(0.5, -0.5) // x, y from -1 to 1\n```\n\n## Transform\n\nApply transformations to container.\n\n```dart\nContainer(\n transform: Matrix4.rotationZ(0.1), // Rotate\n child: Container(...),\n)\n\nContainer(\n transform: Matrix4.translationValues(10, 10, 0), // Translate\n child: Container(...),\n)\n\nContainer(\n transform: Matrix4.diagonal3Values(1.5, 1.5, 1.0), // Scale\n child: Container(...),\n)\n```\n\n## Common Patterns\n\n### Card-like Container\n\n```dart\nContainer(\n margin: EdgeInsets.all(16),\n padding: EdgeInsets.all(16),\n decoration: BoxDecoration(\n color: Colors.white,\n borderRadius: BorderRadius.circular(8),\n boxShadow: [\n BoxShadow(\n color: Colors.black.withOpacity(0.1),\n blurRadius: 4,\n offset: Offset(0, 2),\n ),\n ],\n ),\n child: Text('Card content'),\n)\n```\n\n### Rounded Container with Border\n\n```dart\nContainer(\n padding: EdgeInsets.all(16),\n decoration: BoxDecoration(\n color: Colors.blue,\n borderRadius: BorderRadius.circular(12),\n border: Border.all(\n color: Colors.blue.shade700,\n width: 2,\n ),\n ),\n child: Text('Content', style: TextStyle(color: Colors.white)),\n)\n```\n\n### Gradient Container\n\n```dart\nContainer(\n width: 200,\n height: 200,\n decoration: BoxDecoration(\n gradient: LinearGradient(\n begin: Alignment.topLeft,\n end: Alignment.bottomRight,\n colors: [\n Colors.blue,\n Colors.purple,\n Colors.pink,\n ],\n ),\n borderRadius: BorderRadius.circular(8),\n ),\n child: Center(child: Text('Gradient')),\n)\n```\n\n## Key Points\n\n- `Container` combines sizing, positioning, and decoration\n- Use `BoxDecoration` for visual styling\n- Use `padding` for internal spacing\n- Use `margin` for external spacing\n- Use `alignment` to position child\n- Use `transform` for transformations\n- `color` property is shorthand for `BoxDecoration(color: ...)`\n- When both `color` and `decoration` are set, `decoration` takes precedence\n- Use `foregroundDecoration` for overlays\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/container.dart\n- https://docs.flutter.dev/development/ui/widgets/layout\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5283,"content_sha256":"e131142411abfad5d44f3bb3783009e19252829b2b55fd9603742d57ef423528"},{"filename":"references/layout-flex.md","content":"---\nname: layout-flex\ndescription: Flutter flex layouts - Row, Column, Flex, Flexible, Expanded, and flex properties\n---\n\n# Flex Layouts\n\nFlutter's flex layout system arranges children in a single direction using the Flex algorithm.\n\n## Row\n\nArrange children horizontally.\n\n```dart\nRow(\n mainAxisAlignment: MainAxisAlignment.start, // start, end, center, spaceBetween, spaceAround, spaceEvenly\n crossAxisAlignment: CrossAxisAlignment.center, // start, end, center, stretch, baseline\n mainAxisSize: MainAxisSize.max, // max, min\n textDirection: TextDirection.ltr, // ltr, rtl\n verticalDirection: VerticalDirection.down, // down, up\n children: [\n Container(width: 50, height: 50, color: Colors.red),\n Container(width: 50, height: 50, color: Colors.green),\n Container(width: 50, height: 50, color: Colors.blue),\n ],\n)\n```\n\n## Column\n\nArrange children vertically.\n\n```dart\nColumn(\n mainAxisAlignment: MainAxisAlignment.start,\n crossAxisAlignment: CrossAxisAlignment.center,\n mainAxisSize: MainAxisSize.max,\n textDirection: TextDirection.ltr,\n verticalDirection: VerticalDirection.down,\n children: [\n Container(width: 50, height: 50, color: Colors.red),\n Container(width: 50, height: 50, color: Colors.green),\n Container(width: 50, height: 50, color: Colors.blue),\n ],\n)\n```\n\n## MainAxisAlignment\n\nControl alignment along the main axis.\n\n```dart\n// start - align to start\nRow(\n mainAxisAlignment: MainAxisAlignment.start,\n children: [...],\n)\n\n// end - align to end\nRow(\n mainAxisAlignment: MainAxisAlignment.end,\n children: [...],\n)\n\n// center - center children\nRow(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [...],\n)\n\n// spaceBetween - space evenly between children\nRow(\n mainAxisAlignment: MainAxisAlignment.spaceBetween,\n children: [...],\n)\n\n// spaceAround - space evenly around children\nRow(\n mainAxisAlignment: MainAxisAlignment.spaceAround,\n children: [...],\n)\n\n// spaceEvenly - space evenly including edges\nRow(\n mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n children: [...],\n)\n```\n\n## CrossAxisAlignment\n\nControl alignment along the cross axis.\n\n```dart\n// start - align to start\nColumn(\n crossAxisAlignment: CrossAxisAlignment.start,\n children: [...],\n)\n\n// end - align to end\nColumn(\n crossAxisAlignment: CrossAxisAlignment.end,\n children: [...],\n)\n\n// center - center children\nColumn(\n crossAxisAlignment: CrossAxisAlignment.center,\n children: [...],\n)\n\n// stretch - stretch to fill cross axis\nColumn(\n crossAxisAlignment: CrossAxisAlignment.stretch,\n children: [...],\n)\n\n// baseline - align to baseline\nRow(\n crossAxisAlignment: CrossAxisAlignment.baseline,\n textBaseline: TextBaseline.alphabetic,\n children: [...],\n)\n```\n\n## Flexible\n\nAllow child to take flexible space.\n\n```dart\nRow(\n children: [\n Flexible(\n flex: 1,\n fit: FlexFit.loose, // Can be smaller than available space\n child: Container(color: Colors.red),\n ),\n Flexible(\n flex: 2,\n fit: FlexFit.tight, // Must fill available space (same as Expanded)\n child: Container(color: Colors.green),\n ),\n ],\n)\n```\n\n## Expanded\n\nForce child to fill available space (Flexible with FlexFit.tight).\n\n```dart\nRow(\n children: [\n Expanded(\n flex: 1, // Takes 1/3 of available space\n child: Container(color: Colors.red),\n ),\n Expanded(\n flex: 2, // Takes 2/3 of available space\n child: Container(color: Colors.green),\n ),\n ],\n)\n```\n\n## Spacer\n\nEmpty space that expands.\n\n```dart\nRow(\n children: [\n Text('Start'),\n Spacer(), // Takes all available space\n Text('End'),\n ],\n)\n\nRow(\n children: [\n Text('Start'),\n Spacer(flex: 2), // Takes 2x space compared to other Spacers\n Text('Middle'),\n Spacer(flex: 1), // Takes 1x space\n Text('End'),\n ],\n)\n```\n\n## Flex Widget\n\nGeneric flex widget (base for Row and Column).\n\n```dart\nFlex(\n direction: Axis.horizontal, // horizontal, vertical\n mainAxisAlignment: MainAxisAlignment.start,\n crossAxisAlignment: CrossAxisAlignment.center,\n mainAxisSize: MainAxisSize.max,\n textDirection: TextDirection.ltr,\n verticalDirection: VerticalDirection.down,\n textBaseline: TextBaseline.alphabetic,\n clipBehavior: Clip.none,\n children: [\n Flexible(child: Container()),\n Expanded(child: Container()),\n ],\n)\n```\n\n## Nested Flex Layouts\n\nCombine Row and Column for complex layouts.\n\n```dart\nColumn(\n children: [\n Row(\n children: [\n Expanded(child: Container(color: Colors.red)),\n Expanded(child: Container(color: Colors.green)),\n ],\n ),\n Row(\n children: [\n Expanded(flex: 2, child: Container(color: Colors.blue)),\n Expanded(flex: 1, child: Container(color: Colors.yellow)),\n ],\n ),\n ],\n)\n```\n\n## Key Points\n\n- Use `Row` for horizontal layouts\n- Use `Column` for vertical layouts\n- Use `MainAxisAlignment` to control main axis alignment\n- Use `CrossAxisAlignment` to control cross axis alignment\n- Use `Expanded` to make children fill available space\n- Use `Flexible` for flexible sizing with more control\n- Use `Spacer` to add flexible empty space\n- Use `flex` property to control space distribution\n- Set `mainAxisSize: MainAxisSize.min` to take minimum space\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/basic.dart\n- https://docs.flutter.dev/development/ui/layout\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5362,"content_sha256":"e96cae193316f05488c71470dbeeac34dd35c287d8c2a3edf59bf8283dd37c8d"},{"filename":"references/layout-lists.md","content":"---\nname: layout-lists\ndescription: Flutter list widgets - ListView, ListTile, GridView, and Sliver widgets for scrollable content\n---\n\n# List Widgets\n\nFlutter provides powerful widgets for displaying scrollable lists and grids.\n\n## ListView\n\nDisplay a scrollable list of widgets.\n\n### Basic ListView\n\n```dart\nListView(\n children: [\n ListTile(title: Text('Item 1')),\n ListTile(title: Text('Item 2')),\n ListTile(title: Text('Item 3')),\n ],\n)\n```\n\n### ListView.builder\n\nEfficiently build list items on demand.\n\n```dart\nListView.builder(\n itemCount: items.length,\n itemBuilder: (context, index) {\n return ListTile(\n title: Text(items[index].name),\n subtitle: Text(items[index].description),\n onTap: () {\n // Handle tap\n },\n );\n },\n)\n```\n\n### ListView.separated\n\nList with separators between items.\n\n```dart\nListView.separated(\n itemCount: items.length,\n separatorBuilder: (context, index) => const Divider(),\n itemBuilder: (context, index) {\n return ListTile(\n title: Text(items[index].name),\n );\n },\n)\n```\n\n### ListView Properties\n\n```dart\nListView(\n scrollDirection: Axis.vertical, // vertical, horizontal\n reverse: false, // Reverse scroll direction\n controller: scrollController, // ScrollController\n physics: const AlwaysScrollableScrollPhysics(), // ClampingScrollPhysics, BouncingScrollPhysics, etc.\n padding: const EdgeInsets.all(16),\n shrinkWrap: true, // Take only needed space\n primary: true, // Use primary scroll controller\n children: [...],\n)\n```\n\n## ListTile\n\nStandard list item widget.\n\n```dart\nListTile(\n leading: Icon(Icons.star), // Widget before title\n title: Text('Title'),\n subtitle: Text('Subtitle'),\n trailing: Icon(Icons.arrow_forward), // Widget after title\n isThreeLine: false, // Use three lines for subtitle\n dense: false, // Use less vertical padding\n enabled: true,\n selected: false,\n selectedTileColor: Colors.blue,\n onTap: () {\n // Handle tap\n },\n onLongPress: () {\n // Handle long press\n },\n)\n```\n\n## GridView\n\nDisplay items in a grid layout.\n\n### GridView.count\n\nGrid with fixed number of columns.\n\n```dart\nGridView.count(\n crossAxisCount: 2, // Number of columns\n crossAxisSpacing: 10,\n mainAxisSpacing: 10,\n padding: const EdgeInsets.all(16),\n children: [\n Container(color: Colors.red),\n Container(color: Colors.green),\n Container(color: Colors.blue),\n ],\n)\n```\n\n### GridView.builder\n\nEfficiently build grid items on demand.\n\n```dart\nGridView.builder(\n gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(\n crossAxisCount: 2,\n crossAxisSpacing: 10,\n mainAxisSpacing: 10,\n childAspectRatio: 1.0, // Width/height ratio\n ),\n itemCount: items.length,\n itemBuilder: (context, index) {\n return Container(\n color: Colors.blue,\n child: Center(child: Text('Item $index')),\n );\n },\n)\n```\n\n### GridView.extent\n\nGrid with maximum cross-axis extent.\n\n```dart\nGridView.extent(\n maxCrossAxisExtent: 200, // Maximum width per item\n crossAxisSpacing: 10,\n mainAxisSpacing: 10,\n children: [\n Container(color: Colors.red),\n Container(color: Colors.green),\n ],\n)\n```\n\n## Sliver Widgets\n\nUse Sliver widgets for custom scroll effects in CustomScrollView.\n\n### CustomScrollView\n\n```dart\nCustomScrollView(\n slivers: [\n SliverAppBar(\n expandedHeight: 200,\n floating: false,\n pinned: true,\n flexibleSpace: FlexibleSpaceBar(\n title: Text('Title'),\n background: Image.network('url'),\n ),\n ),\n SliverList(\n delegate: SliverChildBuilderDelegate(\n (context, index) {\n return ListTile(title: Text('Item $index'));\n },\n childCount: 100,\n ),\n ),\n ],\n)\n```\n\n### Common Sliver Widgets\n\n```dart\n// Fixed header\nSliverToBoxAdapter(\n child: Container(height: 100, color: Colors.blue),\n)\n\n// Grid\nSliverGrid(\n gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(\n crossAxisCount: 2,\n ),\n delegate: SliverChildBuilderDelegate(\n (context, index) => Container(color: Colors.red),\n childCount: 10,\n ),\n)\n\n// Padding\nSliverPadding(\n padding: const EdgeInsets.all(16),\n sliver: SliverList(...),\n)\n```\n\n## ScrollController\n\nControl scroll position programmatically.\n\n```dart\nfinal scrollController = ScrollController();\n\n@override\nvoid initState() {\n super.initState();\n scrollController.addListener(() {\n print('Scroll position: ${scrollController.offset}');\n });\n}\n\n@override\nvoid dispose() {\n scrollController.dispose();\n super.dispose();\n}\n\n// Usage\nListView(\n controller: scrollController,\n children: [...],\n)\n\n// Scroll to position\nscrollController.animateTo(\n 500,\n duration: const Duration(milliseconds: 300),\n curve: Curves.easeInOut,\n)\n\n// Jump to position\nscrollController.jumpTo(500);\n```\n\n## Key Points\n\n- Use `ListView` for vertical/horizontal scrolling lists\n- Use `ListView.builder` for efficient list rendering\n- Use `ListView.separated` for lists with separators\n- Use `ListTile` for standard list items\n- Use `GridView` for grid layouts\n- Use `CustomScrollView` with Sliver widgets for advanced scroll effects\n- Use `ScrollController` to control scroll position\n- Set `shrinkWrap: true` for lists inside other scrollable widgets\n- Use `physics` property to control scroll behavior\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/scroll_view.dart\n- https://docs.flutter.dev/development/ui/widgets/lists\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5459,"content_sha256":"5e0d1fd4ac4d09ef20f780af74518b9e704bdd8d0eec7c750043c787012e7c3f"},{"filename":"references/layout-stack.md","content":"---\nname: layout-stack\ndescription: Flutter Stack layout - Stack, Positioned, alignment, and overlapping widgets\n---\n\n# Stack Layout\n\n`Stack` allows widgets to be positioned on top of each other, useful for overlapping content.\n\n## Basic Stack\n\n```dart\nStack(\n children: [\n Container(width: 200, height: 200, color: Colors.blue),\n Container(width: 100, height: 100, color: Colors.red),\n ],\n)\n```\n\n## Stack Alignment\n\nControl how non-positioned children are aligned.\n\n```dart\nStack(\n alignment: Alignment.center, // How to align non-positioned children\n children: [\n Container(width: 200, height: 200, color: Colors.blue),\n Container(width: 100, height: 100, color: Colors.red), // Centered\n ],\n)\n\n// Common alignments\nalignment: Alignment.topLeft\nalignment: Alignment.topCenter\nalignment: Alignment.topRight\nalignment: Alignment.centerLeft\nalignment: Alignment.center\nalignment: Alignment.centerRight\nalignment: Alignment.bottomLeft\nalignment: Alignment.bottomCenter\nalignment: Alignment.bottomRight\n```\n\n## Positioned Widget\n\nPosition children at specific locations.\n\n```dart\nStack(\n children: [\n Container(width: 200, height: 200, color: Colors.blue),\n Positioned(\n top: 10,\n left: 10,\n child: Container(width: 50, height: 50, color: Colors.red),\n ),\n Positioned(\n bottom: 10,\n right: 10,\n child: Container(width: 50, height: 50, color: Colors.green),\n ),\n ],\n)\n```\n\n## Positioned Properties\n\n```dart\nPositioned(\n // Specify all edges\n top: 10,\n right: 10,\n bottom: 10,\n left: 10,\n \n // Or use width/height with edges\n top: 10,\n left: 10,\n width: 100,\n height: 100,\n \n // Or use fill to fill entire stack\n fill: true,\n \n child: Container(color: Colors.red),\n)\n```\n\n## Stack Fit\n\nControl how non-positioned children are sized.\n\n```dart\nStack(\n fit: StackFit.loose, // Children can be smaller than stack (default)\n children: [...],\n)\n\nStack(\n fit: StackFit.expand, // Children fill stack size\n children: [\n Container(), // Fills entire stack\n ],\n)\n\nStack(\n fit: StackFit.passthrough, // Use parent's constraints\n children: [...],\n)\n```\n\n## Clip Behavior\n\nControl clipping of children.\n\n```dart\nStack(\n clipBehavior: Clip.none, // No clipping (default)\n children: [\n Positioned(\n top: -10, // Can extend outside stack\n child: Container(...),\n ),\n ],\n)\n\nStack(\n clipBehavior: Clip.hardEdge, // Clip with hard edges\n children: [...],\n)\n\nStack(\n clipBehavior: Clip.antiAlias, // Clip with anti-aliasing\n children: [...],\n)\n```\n\n## Common Patterns\n\n### Overlay Badge\n\n```dart\nStack(\n children: [\n Container(\n width: 100,\n height: 100,\n color: Colors.blue,\n ),\n Positioned(\n top: 0,\n right: 0,\n child: Container(\n width: 20,\n height: 20,\n decoration: BoxDecoration(\n color: Colors.red,\n shape: BoxShape.circle,\n ),\n child: Center(\n child: Text('3', style: TextStyle(color: Colors.white, fontSize: 12)),\n ),\n ),\n ),\n ],\n)\n```\n\n### Centered Content with Background\n\n```dart\nStack(\n alignment: Alignment.center,\n children: [\n Container(\n width: 200,\n height: 200,\n decoration: BoxDecoration(\n color: Colors.blue,\n shape: BoxShape.circle,\n ),\n ),\n Text('Centered', style: TextStyle(color: Colors.white)),\n ],\n)\n```\n\n### Multiple Overlays\n\n```dart\nStack(\n children: [\n // Background\n Container(width: 200, height: 200, color: Colors.grey),\n \n // Content\n Center(child: Text('Content')),\n \n // Top overlay\n Positioned(\n top: 10,\n left: 10,\n child: Icon(Icons.star, color: Colors.amber),\n ),\n \n // Bottom overlay\n Positioned(\n bottom: 10,\n right: 10,\n child: Icon(Icons.favorite, color: Colors.red),\n ),\n ],\n)\n```\n\n## Key Points\n\n- Use `Stack` to overlap widgets\n- Use `alignment` to position non-positioned children\n- Use `Positioned` to place children at specific locations\n- Use `fit` to control how children fill the stack\n- Use `clipBehavior` to control clipping\n- Children are painted in order (first child is bottom layer)\n- Positioned children ignore alignment\n- Use Stack for badges, overlays, and layered content\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/basic.dart\n- https://docs.flutter.dev/development/ui/layout\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4427,"content_sha256":"a5c13505d01ed9b68d92f963e324e35161ae309baad63b6918ca889f48a427df"},{"filename":"references/widgets-async.md","content":"---\nname: widgets-async\ndescription: Flutter async widgets - FutureBuilder, StreamBuilder, and handling asynchronous operations\n---\n\n# Async Widgets\n\nFlutter provides widgets for building UIs based on asynchronous data.\n\n## FutureBuilder\n\nBuild widgets based on Future completion.\n\n```dart\nFutureBuilder\u003cString>(\n future: fetchData(),\n builder: (context, snapshot) {\n if (snapshot.connectionState == ConnectionState.waiting) {\n return const CircularProgressIndicator();\n }\n \n if (snapshot.hasError) {\n return Text('Error: ${snapshot.error}');\n }\n \n if (snapshot.hasData) {\n return Text('Data: ${snapshot.data}');\n }\n \n return const Text('No data');\n },\n)\n```\n\n## FutureBuilder States\n\n```dart\nFutureBuilder\u003cString>(\n future: fetchData(),\n builder: (context, snapshot) {\n switch (snapshot.connectionState) {\n case ConnectionState.none:\n return const Text('Not started');\n \n case ConnectionState.waiting:\n return const CircularProgressIndicator();\n \n case ConnectionState.active:\n return const Text('Loading...');\n \n case ConnectionState.done:\n if (snapshot.hasError) {\n return Text('Error: ${snapshot.error}');\n }\n return Text('Data: ${snapshot.data}');\n }\n },\n)\n```\n\n## StreamBuilder\n\nBuild widgets based on Stream events.\n\n```dart\nStreamBuilder\u003cint>(\n stream: counterStream(),\n initialData: 0,\n builder: (context, snapshot) {\n if (snapshot.hasError) {\n return Text('Error: ${snapshot.error}');\n }\n \n return Text('Count: ${snapshot.data}');\n },\n)\n```\n\n## StreamBuilder with ConnectionState\n\n```dart\nStreamBuilder\u003cString>(\n stream: dataStream(),\n builder: (context, snapshot) {\n if (snapshot.connectionState == ConnectionState.waiting) {\n return const CircularProgressIndicator();\n }\n \n if (snapshot.hasError) {\n return Text('Error: ${snapshot.error}');\n }\n \n if (!snapshot.hasData) {\n return const Text('No data');\n }\n \n return Text('Data: ${snapshot.data}');\n },\n)\n```\n\n## Complete Example\n\n```dart\nclass DataWidget extends StatelessWidget {\n const DataWidget({super.key});\n\n Future\u003cString> fetchData() async {\n await Future.delayed(const Duration(seconds: 2));\n return 'Data loaded';\n }\n\n @override\n Widget build(BuildContext context) {\n return FutureBuilder\u003cString>(\n future: fetchData(),\n builder: (context, snapshot) {\n if (snapshot.connectionState == ConnectionState.waiting) {\n return const Scaffold(\n body: Center(child: CircularProgressIndicator()),\n );\n }\n \n if (snapshot.hasError) {\n return Scaffold(\n appBar: AppBar(title: const Text('Error')),\n body: Center(\n child: Column(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n const Icon(Icons.error, size: 48, color: Colors.red),\n const SizedBox(height: 16),\n Text('Error: ${snapshot.error}'),\n ElevatedButton(\n onPressed: () {\n // Retry\n },\n child: const Text('Retry'),\n ),\n ],\n ),\n ),\n );\n }\n \n return Scaffold(\n appBar: AppBar(title: const Text('Data')),\n body: Center(\n child: Text('Data: ${snapshot.data}'),\n ),\n );\n },\n );\n }\n}\n```\n\n## StreamBuilder with List\n\n```dart\nStreamBuilder\u003cList\u003cString>>(\n stream: itemsStream(),\n builder: (context, snapshot) {\n if (!snapshot.hasData) {\n return const CircularProgressIndicator();\n }\n \n final items = snapshot.data!;\n \n return ListView.builder(\n itemCount: items.length,\n itemBuilder: (context, index) {\n return ListTile(title: Text(items[index]));\n },\n );\n },\n)\n```\n\n## Key Points\n\n- Use `FutureBuilder` for one-time async operations\n- Use `StreamBuilder` for continuous data streams\n- Check `connectionState` to handle loading states\n- Use `hasError` to check for errors\n- Use `hasData` to check if data is available\n- Provide `initialData` for StreamBuilder when needed\n- Handle all connection states for better UX\n- Use `snapshot.data` to access the result\n- Use `snapshot.error` to access errors\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/async.dart\n- https://docs.flutter.dev/development/ui/interactive#handling-gestures\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4617,"content_sha256":"580607ba135413f2fe1e0cb8083db10cde44f0f4cc856cf7a8e89b28952d9769"},{"filename":"references/widgets-buttons.md","content":"---\nname: widgets-buttons\ndescription: Flutter button widgets - ElevatedButton, TextButton, OutlinedButton, IconButton, and button styling\n---\n\n# Button Widgets\n\nFlutter provides several button widgets following Material Design guidelines.\n\n## ElevatedButton\n\nRaised button with elevation.\n\n```dart\nElevatedButton(\n onPressed: () {\n // Handle press\n },\n onLongPress: () {\n // Handle long press\n },\n style: ElevatedButton.styleFrom(\n backgroundColor: Colors.blue,\n foregroundColor: Colors.white,\n padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),\n shape: RoundedRectangleBorder(\n borderRadius: BorderRadius.circular(8),\n ),\n ),\n child: const Text('Elevated Button'),\n)\n```\n\n## TextButton\n\nFlat button with text.\n\n```dart\nTextButton(\n onPressed: () {\n // Handle press\n },\n style: TextButton.styleFrom(\n foregroundColor: Colors.blue,\n padding: const EdgeInsets.all(16),\n ),\n child: const Text('Text Button'),\n)\n```\n\n## OutlinedButton\n\nButton with outline border.\n\n```dart\nOutlinedButton(\n onPressed: () {\n // Handle press\n },\n style: OutlinedButton.styleFrom(\n foregroundColor: Colors.blue,\n side: const BorderSide(color: Colors.blue, width: 2),\n padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),\n ),\n child: const Text('Outlined Button'),\n)\n```\n\n## IconButton\n\nButton with an icon.\n\n```dart\nIconButton(\n onPressed: () {\n // Handle press\n },\n icon: const Icon(Icons.favorite),\n color: Colors.red,\n iconSize: 24,\n tooltip: 'Like',\n)\n```\n\n## FilledButton\n\nFilled button (Material 3).\n\n```dart\nFilledButton(\n onPressed: () {\n // Handle press\n },\n style: FilledButton.styleFrom(\n backgroundColor: Colors.blue,\n foregroundColor: Colors.white,\n ),\n child: const Text('Filled Button'),\n)\n```\n\n## ButtonBar\n\nGroup buttons horizontally.\n\n```dart\nButtonBar(\n alignment: MainAxisAlignment.center,\n children: [\n TextButton(onPressed: () {}, child: const Text('Cancel')),\n ElevatedButton(onPressed: () {}, child: const Text('OK')),\n ],\n)\n```\n\n## FloatingActionButton\n\nCircular button that floats above content.\n\n```dart\nFloatingActionButton(\n onPressed: () {\n // Handle press\n },\n backgroundColor: Colors.blue,\n foregroundColor: Colors.white,\n child: const Icon(Icons.add),\n)\n\n// Extended FAB\nFloatingActionButton.extended(\n onPressed: () {},\n icon: const Icon(Icons.add),\n label: const Text('Add'),\n)\n```\n\n## Key Points\n\n- Use `ElevatedButton` for primary actions\n- Use `TextButton` for secondary actions\n- Use `OutlinedButton` for outlined style\n- Use `IconButton` for icon-only actions\n- Use `FilledButton` for Material 3 filled style\n- Use `FloatingActionButton` for prominent floating actions\n- Customize buttons with `styleFrom()` method\n- Set `onPressed: null` to disable button\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/material/button.dart\n- https://docs.flutter.dev/development/ui/widgets/material#Buttons\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3000,"content_sha256":"a5d718551abab207ff18b93c42e1347d448331fbeb3d558306919bb750f0c825"},{"filename":"references/widgets-dismissible.md","content":"---\nname: widgets-dismissible\ndescription: Flutter Dismissible - swipe-to-dismiss widgets with callbacks\n---\n\n# Dismissible\n\n`Dismissible` allows widgets to be dismissed by swiping.\n\n## Basic Usage\n\n```dart\nDismissible(\n key: Key(item.id),\n onDismissed: (direction) {\n // Handle dismissal\n setState(() {\n items.remove(item);\n });\n },\n child: ListTile(title: Text(item.name)),\n)\n```\n\n## Dismiss Directions\n\n```dart\nDismissible(\n key: Key(item.id),\n direction: DismissDirection.horizontal, // horizontal, vertical, endToStart, startToEnd, up, down, all\n onDismissed: (direction) {\n if (direction == DismissDirection.endToStart) {\n // Swiped left\n } else {\n // Swiped right\n }\n },\n child: ListTile(title: Text(item.name)),\n)\n```\n\n## Background\n\nShow background when dismissing.\n\n```dart\nDismissible(\n key: Key(item.id),\n background: Container(\n color: Colors.red,\n alignment: Alignment.centerLeft,\n padding: EdgeInsets.only(left: 20),\n child: Icon(Icons.delete, color: Colors.white),\n ),\n secondaryBackground: Container(\n color: Colors.green,\n alignment: Alignment.centerRight,\n padding: EdgeInsets.only(right: 20),\n child: Icon(Icons.archive, color: Colors.white),\n ),\n onDismissed: (direction) {\n if (direction == DismissDirection.endToStart) {\n // Delete\n } else {\n // Archive\n }\n },\n child: ListTile(title: Text(item.name)),\n)\n```\n\n## Confirm Dismissal\n\n```dart\nDismissible(\n key: Key(item.id),\n confirmDismiss: (direction) async {\n // Show confirmation dialog\n return await showDialog\u003cbool>(\n context: context,\n builder: (context) => AlertDialog(\n title: Text('Confirm'),\n content: Text('Delete this item?'),\n actions: [\n TextButton(\n onPressed: () => Navigator.pop(context, false),\n child: Text('Cancel'),\n ),\n ElevatedButton(\n onPressed: () => Navigator.pop(context, true),\n child: Text('Delete'),\n ),\n ],\n ),\n ) ?? false;\n },\n onDismissed: (direction) {\n // Handle dismissal\n },\n child: ListTile(title: Text(item.name)),\n)\n```\n\n## Complete Example\n\n```dart\nListView.builder(\n itemCount: items.length,\n itemBuilder: (context, index) {\n final item = items[index];\n return Dismissible(\n key: Key(item.id),\n direction: DismissDirection.endToStart,\n background: Container(\n color: Colors.red,\n alignment: Alignment.centerRight,\n padding: EdgeInsets.only(right: 20),\n child: Icon(Icons.delete, color: Colors.white),\n ),\n confirmDismiss: (direction) async {\n return await showDialog\u003cbool>(\n context: context,\n builder: (context) => AlertDialog(\n title: Text('Delete?'),\n content: Text('Are you sure?'),\n actions: [\n TextButton(\n onPressed: () => Navigator.pop(context, false),\n child: Text('Cancel'),\n ),\n ElevatedButton(\n onPressed: () => Navigator.pop(context, true),\n child: Text('Delete'),\n ),\n ],\n ),\n ) ?? false;\n },\n onDismissed: (direction) {\n setState(() {\n items.removeAt(index);\n });\n ScaffoldMessenger.of(context).showSnackBar(\n SnackBar(content: Text('Item deleted')),\n );\n },\n child: ListTile(title: Text(item.name)),\n );\n },\n)\n```\n\n## Key Points\n\n- Use `Dismissible` for swipe-to-dismiss\n- Provide unique `key` for each item\n- Use `background` and `secondaryBackground` for visual feedback\n- Use `confirmDismiss` to confirm before dismissing\n- Handle `onDismissed` to update state\n- Set `direction` to control swipe directions\n- Works well in ListView.builder\n- Update list after dismissal\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/dismissible.dart\n- https://docs.flutter.dev/cookbook/gestures/dismissible\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4048,"content_sha256":"e5cf8f08a2f633a3ec8a71d1a1df3b9fa9c738beeaa10f383caf4271de2a3b14"},{"filename":"references/widgets-icons.md","content":"---\nname: widgets-icons\ndescription: Flutter Icon widget, IconData, IconTheme, and icon usage\n---\n\n# Icon Widgets\n\nFlutter provides widgets for displaying icons from icon fonts.\n\n## Icon Widget\n\nDisplay icons from icon fonts.\n\n```dart\nIcon(\n Icons.star,\n size: 24,\n color: Colors.amber,\n semanticLabel: 'Star icon',\n)\n```\n\n## Icon Properties\n\n```dart\nIcon(\n Icons.favorite,\n size: 48, // Icon size in logical pixels\n color: Colors.red, // Icon color\n fill: 0.0, // Fill weight (0.0 to 1.0) for filled icons\n weight: 400, // Font weight (100-900)\n grade: 0, // Grade adjustment (-25 to 200)\n opticalSize: 24, // Optical size adjustment\n semanticLabel: 'Favorite icon', // Accessibility label\n textDirection: TextDirection.ltr, // Text direction\n)\n```\n\n## Material Icons\n\nUse predefined Material icons.\n\n```dart\n// Common icons\nIcon(Icons.home)\nIcon(Icons.search)\nIcon(Icons.favorite)\nIcon(Icons.settings)\nIcon(Icons.person)\nIcon(Icons.add)\nIcon(Icons.delete)\nIcon(Icons.edit)\nIcon(Icons.close)\nIcon(Icons.check)\nIcon(Icons.arrow_back)\nIcon(Icons.arrow_forward)\nIcon(Icons.menu)\nIcon(Icons.more_vert)\n```\n\n## Custom Icons\n\nUse custom icon fonts.\n\n```dart\n// Define custom icon data\nclass CustomIcons {\n static const IconData customIcon = IconData(\n 0xe900, // Unicode code point\n fontFamily: 'CustomIcons',\n fontPackage: null,\n );\n}\n\n// Use custom icon\nIcon(CustomIcons.customIcon)\n```\n\n## IconTheme\n\nProvide icon theme to descendant widgets.\n\n```dart\nIconTheme(\n data: IconThemeData(\n color: Colors.blue,\n size: 24,\n opacity: 1.0,\n ),\n child: Row(\n children: [\n Icon(Icons.star), // Uses theme color\n Icon(Icons.favorite), // Uses theme color\n ],\n ),\n)\n\n// Access theme\nfinal iconTheme = IconTheme.of(context);\nfinal iconColor = iconTheme.color;\nfinal iconSize = iconTheme.size;\n```\n\n## IconButton\n\nInteractive icon button.\n\n```dart\nIconButton(\n icon: Icon(Icons.favorite),\n onPressed: () {\n // Handle press\n },\n iconSize: 24,\n color: Colors.red,\n tooltip: 'Add to favorites',\n splashRadius: 24, // Splash radius\n)\n```\n\n## ImageIcon\n\nUse images as icons.\n\n```dart\nImageIcon(\n AssetImage('assets/icons/custom_icon.png'),\n size: 48,\n color: Colors.blue,\n)\n\nImageIcon(\n NetworkImage('https://example.com/icon.png'),\n size: 48,\n)\n```\n\n## Icon Usage Patterns\n\n```dart\n// In AppBar\nAppBar(\n leading: IconButton(\n icon: Icon(Icons.menu),\n onPressed: () {},\n ),\n actions: [\n IconButton(\n icon: Icon(Icons.search),\n onPressed: () {},\n ),\n ],\n)\n\n// In ListTile\nListTile(\n leading: Icon(Icons.person),\n title: Text('Profile'),\n trailing: Icon(Icons.arrow_forward),\n)\n\n// In buttons\nElevatedButton.icon(\n icon: Icon(Icons.add),\n label: Text('Add'),\n onPressed: () {},\n)\n```\n\n## Key Points\n\n- Use `Icon` widget to display icons\n- Use `Icons` class for Material Design icons\n- Customize icon appearance with `size` and `color`\n- Use `IconTheme` to provide icon theme to descendants\n- Use `IconButton` for interactive icons\n- Use `ImageIcon` for custom image-based icons\n- Provide `semanticLabel` for accessibility\n- Use `fill` property for filled icon variants (Material 3)\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/icon.dart\n- https://docs.flutter.dev/development/ui/widgets/icons\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3334,"content_sha256":"30beb39aaaf070aba3f2fbb869c5bc21b8043e3c52a465b97302b16c107445f1"},{"filename":"references/widgets-images.md","content":"---\nname: widgets-images\ndescription: Flutter Image widget, AssetImage, NetworkImage, ImageProvider, and image loading\n---\n\n# Image Widgets\n\nFlutter provides widgets for displaying images from various sources.\n\n## Image Widget\n\nDisplay images from different sources.\n\n```dart\n// Asset image\nImage.asset(\n 'assets/images/logo.png',\n width: 100,\n height: 100,\n fit: BoxFit.cover,\n)\n\n// Network image\nImage.network(\n 'https://example.com/image.jpg',\n width: 200,\n height: 200,\n loadingBuilder: (context, child, loadingProgress) {\n if (loadingProgress == null) return child;\n return CircularProgressIndicator(\n value: loadingProgress.expectedTotalBytes != null\n ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!\n : null,\n );\n },\n errorBuilder: (context, error, stackTrace) {\n return Icon(Icons.error);\n },\n)\n\n// File image\nImage.file(\n File('/path/to/image.jpg'),\n width: 100,\n height: 100,\n)\n\n// Memory image\nImage.memory(\n Uint8List.fromList(imageBytes),\n width: 100,\n height: 100,\n)\n```\n\n## Image Properties\n\n```dart\nImage.asset(\n 'assets/images/logo.png',\n width: 200,\n height: 200,\n fit: BoxFit.cover, // cover, contain, fill, fitWidth, fitHeight, none, scaleDown\n alignment: Alignment.center,\n repeat: ImageRepeat.noRepeat, // noRepeat, repeat, repeatX, repeatY\n matchTextDirection: false,\n gaplessPlayback: false, // Keep showing old image while loading new one\n filterQuality: FilterQuality.low, // low, medium, high, none\n isAntiAlias: true,\n frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {\n if (wasSynchronouslyLoaded) return child;\n return AnimatedOpacity(\n opacity: frame == null ? 0 : 1,\n duration: const Duration(milliseconds: 200),\n child: child,\n );\n },\n)\n```\n\n## ImageProvider\n\nUse ImageProvider for advanced image loading.\n\n### AssetImage\n\n```dart\nImage(\n image: AssetImage('assets/images/logo.png'),\n width: 100,\n height: 100,\n)\n\n// With package\nAssetImage('assets/logo.png', package: 'my_package')\n```\n\n### NetworkImage\n\n```dart\nImage(\n image: NetworkImage('https://example.com/image.jpg'),\n width: 100,\n height: 100,\n)\n\n// With headers\nNetworkImage(\n 'https://example.com/image.jpg',\n headers: {'Authorization': 'Bearer token'},\n)\n```\n\n### FileImage\n\n```dart\nImage(\n image: FileImage(File('/path/to/image.jpg')),\n width: 100,\n height: 100,\n)\n```\n\n### MemoryImage\n\n```dart\nImage(\n image: MemoryImage(Uint8List.fromList(imageBytes)),\n width: 100,\n height: 100,\n)\n```\n\n## FadeInImage\n\nImage with fade-in animation.\n\n```dart\nFadeInImage.assetNetwork(\n placeholder: 'assets/placeholder.png',\n image: 'https://example.com/image.jpg',\n width: 200,\n height: 200,\n fadeInDuration: const Duration(milliseconds: 300),\n fadeOutDuration: const Duration(milliseconds: 100),\n)\n\nFadeInImage.memoryNetwork(\n placeholder: kTransparentImage, // From transparent_image package\n image: 'https://example.com/image.jpg',\n)\n```\n\n## Image Caching\n\nPrecache images for better performance.\n\n```dart\n// Precache asset image\nprecacheImage(\n AssetImage('assets/images/logo.png'),\n context,\n);\n\n// Precache network image\nprecacheImage(\n NetworkImage('https://example.com/image.jpg'),\n context,\n).then((_) {\n // Image is cached\n});\n\n// Check cache status\nfinal status = await imageProvider.obtainCacheStatus(\n configuration: createLocalImageConfiguration(context),\n);\nprint('Cache status: ${status.status}'); // pending, live, keepAlive\n```\n\n## Image Error Handling\n\n```dart\nImage.network(\n 'https://example.com/image.jpg',\n errorBuilder: (context, error, stackTrace) {\n return Container(\n width: 100,\n height: 100,\n color: Colors.grey[300],\n child: Column(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n Icon(Icons.error, color: Colors.red),\n Text('Failed to load', style: TextStyle(fontSize: 10)),\n ],\n ),\n );\n },\n loadingBuilder: (context, child, loadingProgress) {\n if (loadingProgress == null) return child;\n return Center(\n child: CircularProgressIndicator(\n value: loadingProgress.expectedTotalBytes != null\n ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!\n : null,\n ),\n );\n },\n)\n```\n\n## ImageIcon\n\nUse images as icons.\n\n```dart\nImageIcon(\n AssetImage('assets/icons/custom_icon.png'),\n size: 48,\n color: Colors.blue,\n)\n\nImageIcon(\n NetworkImage('https://example.com/icon.png'),\n size: 48,\n)\n```\n\n## Key Points\n\n- Use `Image.asset()` for local assets\n- Use `Image.network()` for network images\n- Use `Image.file()` for file system images\n- Use `Image.memory()` for in-memory images\n- Use `FadeInImage` for smooth loading transitions\n- Precache images for better performance\n- Always provide error builders for network images\n- Use `BoxFit` to control how images fill their bounds\n- Configure image cache size in `ImageCache` if needed\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/image.dart\n- https://docs.flutter.dev/development/ui/widgets/images\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5134,"content_sha256":"2c2e02262f612f8fd3cfae9e0d00e930ab6f11ee4986d091e91c26db303850f4"},{"filename":"references/widgets-input.md","content":"---\nname: widgets-input\ndescription: Flutter input widgets - TextField, TextFormField, Form, FormField, and input validation\n---\n\n# Input Widgets\n\nFlutter provides text input widgets with validation and form handling.\n\n## TextField\n\nSingle-line text input.\n\n```dart\nTextField(\n decoration: const InputDecoration(\n labelText: 'Label',\n hintText: 'Hint text',\n border: OutlineInputBorder(),\n prefixIcon: Icon(Icons.person),\n suffixIcon: Icon(Icons.clear),\n ),\n keyboardType: TextInputType.emailAddress,\n textInputAction: TextInputAction.next,\n onChanged: (value) {\n // Handle text change\n },\n onSubmitted: (value) {\n // Handle submit\n },\n)\n```\n\n## TextFormField\n\nText input with validation.\n\n```dart\nfinal _formKey = GlobalKey\u003cFormState>();\nfinal _emailController = TextEditingController();\n\nForm(\n key: _formKey,\n child: TextFormField(\n controller: _emailController,\n decoration: const InputDecoration(\n labelText: 'Email',\n border: OutlineInputBorder(),\n ),\n keyboardType: TextInputType.emailAddress,\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Please enter email';\n }\n if (!value.contains('@')) {\n return 'Please enter valid email';\n }\n return null;\n },\n onSaved: (value) {\n // Save value\n },\n ),\n)\n\n// Validate form\nif (_formKey.currentState!.validate()) {\n _formKey.currentState!.save();\n // Process form\n}\n```\n\n## Form\n\nContainer for form fields with validation.\n\n```dart\nfinal _formKey = GlobalKey\u003cFormState>();\n\nForm(\n key: _formKey,\n autovalidateMode: AutovalidateMode.onUserInteraction,\n onChanged: () {\n // Handle form change\n },\n child: Column(\n children: [\n TextFormField(...),\n TextFormField(...),\n ElevatedButton(\n onPressed: () {\n if (_formKey.currentState!.validate()) {\n // Form is valid\n }\n },\n child: const Text('Submit'),\n ),\n ],\n ),\n)\n```\n\n## InputDecoration\n\nCustomize input appearance.\n\n```dart\nInputDecoration(\n labelText: 'Label',\n labelStyle: const TextStyle(color: Colors.blue),\n hintText: 'Hint',\n helperText: 'Helper text',\n errorText: 'Error text',\n prefixIcon: const Icon(Icons.person),\n suffixIcon: IconButton(\n icon: const Icon(Icons.clear),\n onPressed: () {},\n ),\n border: OutlineInputBorder(\n borderRadius: BorderRadius.circular(8),\n ),\n enabledBorder: OutlineInputBorder(\n borderSide: const BorderSide(color: Colors.grey),\n borderRadius: BorderRadius.circular(8),\n ),\n focusedBorder: OutlineInputBorder(\n borderSide: const BorderSide(color: Colors.blue, width: 2),\n borderRadius: BorderRadius.circular(8),\n ),\n errorBorder: OutlineInputBorder(\n borderSide: const BorderSide(color: Colors.red),\n borderRadius: BorderRadius.circular(8),\n ),\n filled: true,\n fillColor: Colors.grey[100],\n)\n```\n\n## TextEditingController\n\nControl text field value programmatically.\n\n```dart\nfinal controller = TextEditingController(text: 'Initial value');\n\nTextField(\n controller: controller,\n)\n\n// Update value\ncontroller.text = 'New value';\n\n// Listen to changes\ncontroller.addListener(() {\n print('Text: ${controller.text}');\n});\n\n// Dispose controller\n@override\nvoid dispose() {\n controller.dispose();\n super.dispose();\n}\n```\n\n## Input Types\n\n```dart\n// Email\nkeyboardType: TextInputType.emailAddress\n\n// Number\nkeyboardType: TextInputType.number\n\n// Phone\nkeyboardType: TextInputType.phone\n\n// URL\nkeyboardType: TextInputType.url\n\n// Multiline\nmaxLines: null,\nkeyboardType: TextInputType.multiline\n```\n\n## Key Points\n\n- Use `TextField` for simple text input\n- Use `TextFormField` for validated input\n- Wrap fields in `Form` for form validation\n- Use `TextEditingController` to control text value\n- Customize appearance with `InputDecoration`\n- Set `keyboardType` for appropriate keyboard\n- Use `validator` for input validation\n- Call `dispose()` on controllers to prevent memory leaks\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/form.dart\n- https://docs.flutter.dev/development/ui/widgets/material#Input%20and%20selections\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4178,"content_sha256":"5d0240621fe1db344825eb1e11a5711666b444be15ce3ecf76013780ed4d1fff"},{"filename":"references/widgets-pageview.md","content":"---\nname: widgets-pageview\ndescription: Flutter PageView - swipeable pages, PageController, and page navigation\n---\n\n# PageView\n\n`PageView` displays a scrollable list of pages that users can swipe between.\n\n## Basic PageView\n\n```dart\nPageView(\n children: [\n Container(color: Colors.red, child: Center(child: Text('Page 1'))),\n Container(color: Colors.green, child: Center(child: Text('Page 2'))),\n Container(color: Colors.blue, child: Center(child: Text('Page 3'))),\n ],\n)\n```\n\n## PageController\n\nControl page navigation programmatically.\n\n```dart\nclass PageViewExample extends StatefulWidget {\n const PageViewExample({super.key});\n\n @override\n State\u003cPageViewExample> createState() => _PageViewExampleState();\n}\n\nclass _PageViewExampleState extends State\u003cPageViewExample> {\n final PageController _controller = PageController();\n\n @override\n void dispose() {\n _controller.dispose();\n super.dispose();\n }\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n Expanded(\n child: PageView(\n controller: _controller,\n children: [\n Container(color: Colors.red),\n Container(color: Colors.green),\n Container(color: Colors.blue),\n ],\n ),\n ),\n Row(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n ElevatedButton(\n onPressed: () => _controller.previousPage(\n duration: Duration(milliseconds: 300),\n curve: Curves.easeInOut,\n ),\n child: const Text('Previous'),\n ),\n ElevatedButton(\n onPressed: () => _controller.nextPage(\n duration: Duration(milliseconds: 300),\n curve: Curves.easeInOut,\n ),\n child: const Text('Next'),\n ),\n ],\n ),\n ],\n );\n }\n}\n```\n\n## PageView.builder\n\nBuild pages on demand.\n\n```dart\nPageView.builder(\n itemCount: pages.length,\n itemBuilder: (context, index) {\n return Container(\n color: Colors.blue,\n child: Center(child: Text('Page $index')),\n );\n },\n)\n```\n\n## PageView Properties\n\n```dart\nPageView(\n scrollDirection: Axis.horizontal, // horizontal, vertical\n reverse: false, // Reverse scroll direction\n controller: _controller,\n physics: PageScrollPhysics(), // ClampingScrollPhysics, BouncingScrollPhysics\n pageSnapping: true, // Snap to pages\n onPageChanged: (index) {\n print('Page changed to $index');\n },\n children: [...],\n)\n```\n\n## Initial Page\n\n```dart\nPageController(\n initialPage: 2, // Start at page 2\n viewportFraction: 1.0, // Page width fraction (0.0 to 1.0)\n)\n\nPageView(\n controller: PageController(initialPage: 1),\n children: [...],\n)\n```\n\n## Viewport Fraction\n\nShow multiple pages at once.\n\n```dart\nPageView(\n controller: PageController(viewportFraction: 0.8),\n children: [\n Container(color: Colors.red),\n Container(color: Colors.green),\n Container(color: Colors.blue),\n ],\n)\n```\n\n## Key Points\n\n- Use `PageView` for swipeable pages\n- Use `PageController` to control navigation\n- Use `PageView.builder` for dynamic pages\n- Set `scrollDirection` for horizontal/vertical scrolling\n- Use `onPageChanged` to track page changes\n- Set `viewportFraction` to show multiple pages\n- Always dispose `PageController`\n- Use `pageSnapping` to snap to pages\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/page_view.dart\n- https://docs.flutter.dev/cookbook/navigation/page-view\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3603,"content_sha256":"cf0a58aaabebf9a7a88f46aea8d000e0702169e74929de97bb6811acde420103"},{"filename":"references/widgets-refresh-indicator.md","content":"---\nname: widgets-refresh-indicator\ndescription: Flutter RefreshIndicator - pull-to-refresh functionality for scrollable content\n---\n\n# RefreshIndicator\n\n`RefreshIndicator` provides pull-to-refresh functionality for scrollable widgets.\n\n## Basic Usage\n\n```dart\nRefreshIndicator(\n onRefresh: () async {\n // Fetch new data\n await fetchData();\n },\n child: ListView(\n children: [\n ListTile(title: Text('Item 1')),\n ListTile(title: Text('Item 2')),\n ListTile(title: Text('Item 3')),\n ],\n ),\n)\n```\n\n## With Future\n\n```dart\nRefreshIndicator(\n onRefresh: () async {\n final data = await fetchData();\n setState(() {\n _items = data;\n });\n },\n child: ListView.builder(\n itemCount: _items.length,\n itemBuilder: (context, index) {\n return ListTile(title: Text(_items[index]));\n },\n ),\n)\n```\n\n## Customization\n\n```dart\nRefreshIndicator(\n onRefresh: () async {\n await fetchData();\n },\n color: Colors.blue, // Indicator color\n backgroundColor: Colors.white, // Background color\n strokeWidth: 3.0, // Indicator stroke width\n displacement: 40.0, // Displacement from top\n edgeOffset: 0.0, // Edge offset\n triggerMode: RefreshIndicatorTriggerMode.onEdge, // onEdge, anywhere\n child: ListView(...),\n)\n```\n\n## Complete Example\n\n```dart\nclass RefreshableList extends StatefulWidget {\n const RefreshableList({super.key});\n\n @override\n State\u003cRefreshableList> createState() => _RefreshableListState();\n}\n\nclass _RefreshableListState extends State\u003cRefreshableList> {\n List\u003cString> _items = ['Item 1', 'Item 2', 'Item 3'];\n\n Future\u003cvoid> _refresh() async {\n // Simulate network delay\n await Future.delayed(Duration(seconds: 2));\n \n setState(() {\n _items = ['New Item 1', 'New Item 2', 'New Item 3'];\n });\n }\n\n @override\n Widget build(BuildContext context) {\n return RefreshIndicator(\n onRefresh: _refresh,\n child: ListView.builder(\n itemCount: _items.length,\n itemBuilder: (context, index) {\n return ListTile(title: Text(_items[index]));\n },\n ),\n );\n }\n}\n```\n\n## Key Points\n\n- Use `RefreshIndicator` for pull-to-refresh\n- Wrap scrollable widgets (ListView, GridView, etc.)\n- `onRefresh` must return a Future\n- Customize appearance with properties\n- Works with any scrollable widget\n- Provides standard Material Design refresh indicator\n- Use `triggerMode` to control when refresh triggers\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/material/refresh_indicator.dart\n- https://docs.flutter.dev/cookbook/design/pull-to-refresh\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2608,"content_sha256":"1e3416b1fb81b09e155b2f74e3192118f88c499be4ea3dd6ed1a382ac4a0822f"},{"filename":"references/widgets-tabs.md","content":"---\nname: widgets-tabs\ndescription: Flutter TabBar and TabController - tab navigation, tab views, and tab management\n---\n\n# TabBar and TabController\n\nFlutter provides `TabBar` and `TabController` for tab navigation.\n\n## Basic TabBar\n\n```dart\nDefaultTabController(\n length: 3,\n child: Scaffold(\n appBar: AppBar(\n title: Text('Tabs'),\n bottom: TabBar(\n tabs: [\n Tab(icon: Icon(Icons.home), text: 'Home'),\n Tab(icon: Icon(Icons.search), text: 'Search'),\n Tab(icon: Icon(Icons.person), text: 'Profile'),\n ],\n ),\n ),\n body: TabBarView(\n children: [\n HomeScreen(),\n SearchScreen(),\n ProfileScreen(),\n ],\n ),\n ),\n)\n```\n\n## TabController\n\nControl tabs programmatically.\n\n```dart\nclass TabExample extends StatefulWidget {\n const TabExample({super.key});\n\n @override\n State\u003cTabExample> createState() => _TabExampleState();\n}\n\nclass _TabExampleState extends State\u003cTabExample>\n with SingleTickerProviderStateMixin {\n late TabController _tabController;\n\n @override\n void initState() {\n super.initState();\n _tabController = TabController(length: 3, vsync: this);\n }\n\n @override\n void dispose() {\n _tabController.dispose();\n super.dispose();\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: Text('Tabs'),\n bottom: TabBar(\n controller: _tabController,\n tabs: [\n Tab(text: 'Tab 1'),\n Tab(text: 'Tab 2'),\n Tab(text: 'Tab 3'),\n ],\n ),\n ),\n body: TabBarView(\n controller: _tabController,\n children: [\n Container(color: Colors.red),\n Container(color: Colors.green),\n Container(color: Colors.blue),\n ],\n ),\n );\n }\n}\n```\n\n## TabBar Properties\n\n```dart\nTabBar(\n controller: _tabController,\n tabs: [...],\n isScrollable: false, // Allow scrolling if tabs overflow\n indicatorColor: Colors.blue, // Indicator color\n indicatorWeight: 2.0, // Indicator thickness\n indicatorSize: TabBarIndicatorSize.tab, // tab, label\n labelColor: Colors.blue, // Selected tab label color\n unselectedLabelColor: Colors.grey, // Unselected tab label color\n labelStyle: TextStyle(fontSize: 16), // Selected tab label style\n unselectedLabelStyle: TextStyle(fontSize: 14), // Unselected tab label style\n onTap: (index) {\n print('Tab $index tapped');\n },\n)\n```\n\n## TabBarView\n\n```dart\nTabBarView(\n controller: _tabController,\n children: [\n HomeScreen(),\n SearchScreen(),\n ProfileScreen(),\n ],\n physics: BouncingScrollPhysics(), // Scroll physics\n)\n```\n\n## TabController Methods\n\n```dart\n// Animate to tab\n_tabController.animateTo(2);\n\n// Listen to tab changes\n_tabController.addListener(() {\n if (!_tabController.indexIsChanging) {\n print('Tab changed to ${_tabController.index}');\n }\n});\n\n// Get current index\nfinal currentIndex = _tabController.index;\n\n// Get previous index\nfinal previousIndex = _tabController.previousIndex;\n```\n\n## Key Points\n\n- Use `DefaultTabController` for simple cases\n- Use `TabController` for programmatic control\n- Implement `SingleTickerProviderStateMixin` for TabController\n- Always dispose `TabController`\n- Use `TabBar` in AppBar bottom\n- Use `TabBarView` for tab content\n- Customize appearance with TabBar properties\n- Listen to tab changes with `addListener()`\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/material/tabs.dart\n- https://docs.flutter.dev/cookbook/design/tabs\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3577,"content_sha256":"ce7fff4da5ac22631146b72d43bef3b2208aa4a801a7a20580b557c7e55d90e9"},{"filename":"references/widgets-text.md","content":"---\nname: widgets-text\ndescription: Flutter Text widget, TextStyle, RichText, TextSpan, and text styling\n---\n\n# Text Widgets\n\nFlutter provides powerful text widgets for displaying and styling text in your app.\n\n## Text Widget\n\nBasic text display widget.\n\n```dart\nText(\n 'Hello, Flutter!',\n style: TextStyle(\n fontSize: 24,\n fontWeight: FontWeight.bold,\n color: Colors.blue,\n ),\n)\n```\n\n## TextStyle\n\nConfigure text appearance with `TextStyle`.\n\n```dart\nTextStyle(\n fontSize: 16,\n fontWeight: FontWeight.w500, // w100-w900, normal, bold\n fontStyle: FontStyle.italic, // normal, italic\n color: Colors.black87,\n letterSpacing: 1.2,\n wordSpacing: 2.0,\n height: 1.5, // Line height multiplier\n decoration: TextDecoration.underline, // none, underline, overline, lineThrough\n decorationColor: Colors.red,\n decorationStyle: TextDecorationStyle.solid, // solid, double, dotted, dashed, wavy\n backgroundColor: Colors.yellow,\n shadows: [\n Shadow(\n color: Colors.black26,\n offset: const Offset(2, 2),\n blurRadius: 4,\n ),\n ],\n)\n```\n\n## RichText\n\nDisplay text with multiple styles using `TextSpan`.\n\n```dart\nRichText(\n text: TextSpan(\n style: DefaultTextStyle.of(context).style,\n children: \u003cTextSpan>[\n const TextSpan(\n text: 'Hello ',\n style: TextStyle(color: Colors.black),\n ),\n TextSpan(\n text: 'Flutter',\n style: TextStyle(\n color: Colors.blue,\n fontWeight: FontWeight.bold,\n ),\n recognizer: TapGestureRecognizer()\n ..onTap = () {\n // Handle tap\n },\n ),\n const TextSpan(\n text: '!',\n style: TextStyle(color: Colors.black),\n ),\n ],\n ),\n)\n```\n\n## Text Properties\n\n```dart\nText(\n 'Hello, Flutter!',\n textAlign: TextAlign.center, // left, right, center, justify, start, end\n textDirection: TextDirection.ltr, // ltr, rtl\n overflow: TextOverflow.ellipsis, // clip, fade, ellipsis, visible\n maxLines: 2,\n textScaleFactor: 1.2, // Scale text size\n softWrap: true, // Whether to break text at soft line breaks\n textWidthBasis: TextWidthBasis.parent, // parent, longestLine\n selectionColor: Colors.blue, // Color for selected text\n)\n```\n\n## TextTheme\n\nUse theme text styles for consistent typography.\n\n```dart\nText(\n 'Headline',\n style: Theme.of(context).textTheme.headlineLarge,\n)\n\n// Available text styles:\n// displayLarge, displayMedium, displaySmall\n// headlineLarge, headlineMedium, headlineSmall\n// titleLarge, titleMedium, titleSmall\n// bodyLarge, bodyMedium, bodySmall\n// labelLarge, labelMedium, labelSmall\n```\n\n## SelectableText\n\nMake text selectable.\n\n```dart\nSelectableText(\n 'This text can be selected',\n style: const TextStyle(fontSize: 16),\n onTap: () {\n // Handle tap\n },\n)\n```\n\n## TextField\n\nSingle-line text input.\n\n```dart\nTextField(\n decoration: const InputDecoration(\n labelText: 'Enter text',\n hintText: 'Hint text',\n border: OutlineInputBorder(),\n ),\n onChanged: (value) {\n // Handle text change\n },\n)\n```\n\n## TextFormField\n\nText input with validation.\n\n```dart\nTextFormField(\n decoration: const InputDecoration(\n labelText: 'Email',\n border: OutlineInputBorder(),\n ),\n validator: (value) {\n if (value == null || value.isEmpty) {\n return 'Please enter email';\n }\n if (!value.contains('@')) {\n return 'Please enter valid email';\n }\n return null;\n },\n)\n```\n\n## Key Points\n\n- Use `Text` for simple text display\n- Use `TextStyle` to customize text appearance\n- Use `RichText` with `TextSpan` for multi-style text\n- Use `TextTheme` for consistent typography\n- Use `SelectableText` for selectable text\n- Use `TextField` for single-line input\n- Use `TextFormField` for validated input\n- Configure `overflow` and `maxLines` for text that might not fit\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/text.dart\n- https://docs.flutter.dev/development/ui/widgets/text\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3981,"content_sha256":"05afe0f6ccfbb37079fa08fc769164b5698bf7baa749094260bbbe31dc2303f3"},{"filename":"references/widgets-value-listenable.md","content":"---\nname: widgets-value-listenable\ndescription: Flutter ValueListenableBuilder - building widgets based on ValueListenable changes\n---\n\n# ValueListenableBuilder\n\n`ValueListenableBuilder` rebuilds widgets when a `ValueListenable` value changes.\n\n## Basic Usage\n\n```dart\nfinal counter = ValueNotifier\u003cint>(0);\n\nValueListenableBuilder\u003cint>(\n valueListenable: counter,\n builder: (context, value, child) {\n return Text('Count: $value');\n },\n)\n\n// Update value\ncounter.value++;\n```\n\n## With ValueNotifier\n\n```dart\nclass CounterModel {\n final ValueNotifier\u003cint> count = ValueNotifier\u003cint>(0);\n\n void increment() {\n count.value++;\n }\n\n void dispose() {\n count.dispose();\n }\n}\n\n// Usage\nfinal model = CounterModel();\n\nValueListenableBuilder\u003cint>(\n valueListenable: model.count,\n builder: (context, count, child) {\n return Column(\n children: [\n Text('Count: $count'),\n ElevatedButton(\n onPressed: model.increment,\n child: const Text('Increment'),\n ),\n ],\n );\n },\n)\n```\n\n## Performance Optimization\n\nUse `child` parameter to avoid rebuilding static widgets.\n\n```dart\nValueListenableBuilder\u003cint>(\n valueListenable: counter,\n builder: (context, value, child) {\n return Row(\n children: [\n Text('Count: $value'), // Rebuilds\n child!, // Doesn't rebuild\n ],\n );\n },\n child: const ExpensiveWidget(), // Built once\n)\n```\n\n## Multiple ValueListenables\n\nCombine multiple ValueListenables.\n\n```dart\nValueListenableBuilder\u003cint>(\n valueListenable: counter1,\n builder: (context, value1, child) {\n return ValueListenableBuilder\u003cint>(\n valueListenable: counter2,\n builder: (context, value2, child) {\n return Text('Total: ${value1 + value2}');\n },\n );\n },\n)\n```\n\n## Key Points\n\n- Use `ValueListenableBuilder` for simple reactive updates\n- More efficient than `setState` for single values\n- Use `child` parameter for performance optimization\n- Always dispose `ValueNotifier` to prevent leaks\n- Works with `ValueNotifier`, `Animation`, and other `ValueListenable` implementations\n- Rebuilds only when value changes\n- Simpler than `StreamBuilder` for single values\n\n\u003c!--\nSource references:\n- https://github.com/flutter/flutter/tree/main/packages/flutter/lib/src/widgets/value_listenable_builder.dart\n- https://api.flutter.dev/flutter/widgets/ValueListenableBuilder-class.html\n-->\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2390,"content_sha256":"c6cdc4fea59323d4583fd8421c7ea2d1adf464538847ebb9953b37ff5c0017d7"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Flutter","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"The skill is based on Flutter framework, generated at 2026-01-31.","type":"text"}]}]},{"type":"paragraph","content":[{"text":"Flutter is Google's SDK for crafting beautiful, fast user experiences for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source.","type":"text"}]},{"type":"paragraph","content":[{"text":"Flutter uses Dart as its programming language and follows a widget-based architecture where everything is a widget. The framework provides hot reload for fast development cycles, a rich set of Material Design and Cupertino widgets, and excellent performance through compiled code.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core References","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Widget System","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"StatelessWidget, StatefulWidget, Widget lifecycle, keys","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"core-widgets","type":"text","marks":[{"type":"link","attrs":{"href":"references/core-widgets.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"State Management","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"setState, StatefulWidget, ValueNotifier, ChangeNotifier","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"core-state-management","type":"text","marks":[{"type":"link","attrs":{"href":"references/core-state-management.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Layout System","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Row, Column, Stack, Flex, constraints, sizing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"core-layout","type":"text","marks":[{"type":"link","attrs":{"href":"references/core-layout.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"BuildContext","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Context usage, InheritedWidget, theme access","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"core-build-context","type":"text","marks":[{"type":"link","attrs":{"href":"references/core-build-context.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"InheritedWidget","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sharing data down widget tree, InheritedWidget patterns","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-inherited-widget","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-inherited-widget.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Widgets","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Basic Widgets","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Text & Styling","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Text widget, TextStyle, RichText, TextSpan","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-text","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-text.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Images","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Image widget, AssetImage, NetworkImage, ImageProvider","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-images","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-images.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Icons","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Icon widget, IconData, IconTheme","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-icons","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-icons.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Buttons","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ElevatedButton, TextButton, OutlinedButton, IconButton","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-buttons","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-buttons.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Input Fields","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"TextField, TextFormField, Form, FormField","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-input","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-input.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Async Widgets","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FutureBuilder, StreamBuilder, async operations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-async","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-async.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ValueListenableBuilder","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Building widgets based on ValueListenable changes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-value-listenable","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-value-listenable.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PageView","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Swipeable pages, PageController, page navigation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-pageview","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-pageview.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"RefreshIndicator","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pull-to-refresh functionality","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-refresh-indicator","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-refresh-indicator.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Dismissible","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Swipe-to-dismiss widgets","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-dismissible","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-dismissible.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"TabBar & Tabs","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tab navigation, TabController, TabBarView","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"widgets-tabs","type":"text","marks":[{"type":"link","attrs":{"href":"references/widgets-tabs.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Forms & Validation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Form validation, validators, form handling","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-forms-validation","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-forms-validation.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Layout Widgets","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flex Layouts","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Row, Column, Flex, Flexible, Expanded","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"layout-flex","type":"text","marks":[{"type":"link","attrs":{"href":"references/layout-flex.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stack Layout","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stack, Positioned, alignment","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"layout-stack","type":"text","marks":[{"type":"link","attrs":{"href":"references/layout-stack.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Container","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Container, BoxDecoration, padding, margin","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"layout-container","type":"text","marks":[{"type":"link","attrs":{"href":"references/layout-container.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List Views","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ListView, ListTile, GridView, Sliver widgets","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"layout-lists","type":"text","marks":[{"type":"link","attrs":{"href":"references/layout-lists.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slivers","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CustomScrollView, SliverList, SliverGrid, advanced scrolling","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-slivers","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-slivers.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Scroll Controller","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Programmatic scroll control, scroll listeners","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-scroll-controller","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-scroll-controller.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Features","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Navigation","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Navigator","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Navigator.push, Navigator.pop, routes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-navigation","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-navigation.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Named Routes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Route configuration, onGenerateRoute","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-named-routes","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-named-routes.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Router","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GoRouter, declarative routing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-router","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-router.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Animations","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Implicit Animations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AnimatedContainer, AnimatedOpacity, AnimatedSize","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-implicit-animations","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-implicit-animations.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Explicit Animations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AnimationController, Tween, AnimationBuilder","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-explicit-animations","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-explicit-animations.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hero Animations","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hero widget, shared element transitions","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-hero-animations","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-hero-animations.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Material Design","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Material App","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MaterialApp, Theme, ThemeData","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-material-app","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-material-app.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Material Components","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AppBar, Scaffold, Drawer, BottomNavigationBar","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-material-components","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-material-components.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Material 3","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Material 3 design system, color schemes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-material-3","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-material-3.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Cupertino (iOS)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cupertino Widgets","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"iOS-style widgets, CupertinoApp, CupertinoNavigationBar","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-cupertino","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-cupertino.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"UI Components","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Dialogs & Modals","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AlertDialog, showDialog, showModalBottomSheet","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-dialogs","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-dialogs.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Focus Management","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FocusNode, FocusScope, keyboard navigation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-focus","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-focus.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Platform Integration","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Platform Channels","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MethodChannel, EventChannel, native communication","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-platform-channels","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-platform-channels.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Platform Views","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AndroidView, UiKitView, embedding native views","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-platform-views","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-platform-views.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Assets & Resources","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Asset management, pubspec.yaml, asset loading","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-assets","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-assets.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTTP & Networking","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HTTP requests, API calls, JSON parsing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-http","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-http.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Responsive Design","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MediaQuery, LayoutBuilder, screen adaptation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-responsive","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-responsive.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Keys","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ValueKey, ObjectKey, GlobalKey, when to use keys","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-keys","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-keys.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Widget Lifecycle","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"initState, dispose, lifecycle management","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-lifecycle","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-lifecycle.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error Handling","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Try-catch, error widgets, error boundaries","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-error-handling","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-error-handling.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PopScope","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Handle back button and navigation pop events","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"features-pop-scope","type":"text","marks":[{"type":"link","attrs":{"href":"references/features-pop-scope.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Advanced","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Custom Paint","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CustomPainter, Canvas, custom graphics","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"advanced-custom-paint","type":"text","marks":[{"type":"link","attrs":{"href":"references/advanced-custom-paint.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Gestures","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GestureDetector, GestureRecognizer, drag and drop","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"advanced-gestures","type":"text","marks":[{"type":"link","attrs":{"href":"references/advanced-gestures.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Performance","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Performance optimization, const constructors, keys","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"advanced-performance","type":"text","marks":[{"type":"link","attrs":{"href":"references/advanced-performance.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Testing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Widget testing, integration testing, test utilities","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"advanced-testing","type":"text","marks":[{"type":"link","attrs":{"href":"references/advanced-testing.md","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Best Practices","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"State Management","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"When to use setState, state lifting, patterns","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"best-practices-state","type":"text","marks":[{"type":"link","attrs":{"href":"references/best-practices-state.md","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Performance","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Optimization techniques, const usage, patterns","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"best-practices-performance","type":"text","marks":[{"type":"link","attrs":{"href":"references/best-practices-performance.md","title":null}}]}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"flutter","author":"@skillopedia","source":{"stars":19,"repo_name":"skills","origin_url":"https://github.com/hairyf/skills/blob/HEAD/skills/flutter/SKILL.md","repo_owner":"hairyf","body_sha256":"00c058cccc63778ed2f6b06a9764de87c19cf64d1cebb58c0e6c1219a55b4c66","cluster_key":"1050debcfd6e4793295c713d862709e3f728237ea17bf94265685a7fd31302bb","clean_bundle":{"format":"clean-skill-bundle-v1","source":"hairyf/skills/skills/flutter/SKILL.md","attachments":[{"id":"3c1b38b1-8d18-5660-af6e-6c3d66ae1392","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/3c1b38b1-8d18-5660-af6e-6c3d66ae1392/attachment.md","path":"GENERATION.md","size":137,"sha256":"000fb5cd2cffc60fbd71c16bb7d744600c018c18e29bb0910539de0aa046de3c","contentType":"text/markdown; charset=utf-8"},{"id":"3b876f64-0c78-5b24-b5f0-2f938480c963","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/3b876f64-0c78-5b24-b5f0-2f938480c963/attachment.md","path":"references/advanced-custom-paint.md","size":4512,"sha256":"762f783d3a6bbef8f5c93335d5307bc83a0a3d7d2bc72193d09a44ee9682fb30","contentType":"text/markdown; charset=utf-8"},{"id":"2e17f6ff-9ece-5217-8d64-bb6b255ecd98","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2e17f6ff-9ece-5217-8d64-bb6b255ecd98/attachment.md","path":"references/advanced-gestures.md","size":5123,"sha256":"8b0a4a0b3cefe50ed51e02333ce0b5b33b49a06815cf730321084b9a2a5345d8","contentType":"text/markdown; charset=utf-8"},{"id":"8a97175e-8a5c-5788-a2ef-7d2843a557eb","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8a97175e-8a5c-5788-a2ef-7d2843a557eb/attachment.md","path":"references/advanced-performance.md","size":4354,"sha256":"fa3ee9a9acf5f177558ccdc9caa032698835a98f8cbf32fa35abc79500e2917a","contentType":"text/markdown; charset=utf-8"},{"id":"79d0aa50-625c-567a-9518-a35c06849615","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/79d0aa50-625c-567a-9518-a35c06849615/attachment.md","path":"references/advanced-testing.md","size":4516,"sha256":"068cf59dadacfd062bc7b7637681b361c49b2bc3c4bdd0182348226555c49a90","contentType":"text/markdown; charset=utf-8"},{"id":"c54eb613-e511-551b-bf70-447931e9f044","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c54eb613-e511-551b-bf70-447931e9f044/attachment.md","path":"references/best-practices-performance.md","size":3902,"sha256":"5b424adb2cf0ae38b5d8f349b08ea3886b761b82f36929d34faeb245dd91e717","contentType":"text/markdown; charset=utf-8"},{"id":"68708265-f05b-51ca-9241-358e6758ceb9","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/68708265-f05b-51ca-9241-358e6758ceb9/attachment.md","path":"references/best-practices-state.md","size":4603,"sha256":"3178f1f9b6b2a7e492aa198752802b04a296e30cdf19af17c02f509223e0a056","contentType":"text/markdown; charset=utf-8"},{"id":"8f91d11a-e1d5-5099-a199-65b9a7685ad8","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8f91d11a-e1d5-5099-a199-65b9a7685ad8/attachment.md","path":"references/core-build-context.md","size":5711,"sha256":"c2add17c5e327f0d7d55e11c836ccc3627466ea17d8ba526d2dc3c8e63bc906f","contentType":"text/markdown; charset=utf-8"},{"id":"7918a061-b9a8-58a9-91fb-27665a7b3b92","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7918a061-b9a8-58a9-91fb-27665a7b3b92/attachment.md","path":"references/core-layout.md","size":5538,"sha256":"089411d12da9f8443067d2bad1dc85f3e93aecfdddaebc8b52d92cc920c624e6","contentType":"text/markdown; charset=utf-8"},{"id":"affe3735-e1d2-554f-8066-2f23302f8328","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/affe3735-e1d2-554f-8066-2f23302f8328/attachment.md","path":"references/core-state-management.md","size":4984,"sha256":"4b1b852eb3e54b2f23556e5351ae93105139f155524969b0bae508404bc8db58","contentType":"text/markdown; charset=utf-8"},{"id":"9d5e2c08-2618-596a-88dc-28d4e51782d7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/9d5e2c08-2618-596a-88dc-28d4e51782d7/attachment.md","path":"references/core-widgets.md","size":4173,"sha256":"27fcd7e1397418012636e278dfe863b07a5c08b3442bac242d53f6a439f83b45","contentType":"text/markdown; charset=utf-8"},{"id":"82ec0afe-4b3e-529a-9a2e-8532fc4396b2","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/82ec0afe-4b3e-529a-9a2e-8532fc4396b2/attachment.md","path":"references/features-assets.md","size":3013,"sha256":"f2975c3794e40b0f342a81c9c9f1780484a23f016308cf1ec41ca07132561ceb","contentType":"text/markdown; charset=utf-8"},{"id":"a2635e34-5225-567a-b439-c09f66d74e2b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a2635e34-5225-567a-b439-c09f66d74e2b/attachment.md","path":"references/features-cupertino.md","size":4221,"sha256":"bb4309be46425181bdee30e5f779f5b8b545ba6b2de5c49f1ece2055297e7165","contentType":"text/markdown; charset=utf-8"},{"id":"0206f835-9b0f-5f44-9c29-fd3a163fa910","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0206f835-9b0f-5f44-9c29-fd3a163fa910/attachment.md","path":"references/features-dialogs.md","size":4612,"sha256":"649b00f87876a21362474d4dedd136d62fd3b09b9a7f52e823f0431d78cc34d1","contentType":"text/markdown; charset=utf-8"},{"id":"1c7a05bb-73b4-53e5-bed3-18e3737896e0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/1c7a05bb-73b4-53e5-bed3-18e3737896e0/attachment.md","path":"references/features-error-handling.md","size":4141,"sha256":"db10059c25873171a09bfd7e9f5d6d353ff255403b336ac00edcef032f65d6bd","contentType":"text/markdown; charset=utf-8"},{"id":"4f742954-3ecb-53c9-92d7-0094f023d9e4","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4f742954-3ecb-53c9-92d7-0094f023d9e4/attachment.md","path":"references/features-explicit-animations.md","size":6337,"sha256":"f2d753e14cf9c38a1998912d54c4c26cbf6f2678d8c3ed6f0cafbc12988d93b4","contentType":"text/markdown; charset=utf-8"},{"id":"d643b8b3-e06d-51be-8e27-cbd5c40f90d1","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d643b8b3-e06d-51be-8e27-cbd5c40f90d1/attachment.md","path":"references/features-focus.md","size":3402,"sha256":"2f46f9475f3160b6b1d43f16e01d39730418ce74fcd48529bf35cc1dced26fa3","contentType":"text/markdown; charset=utf-8"},{"id":"0f2ac82a-5815-5de8-abd9-6ddf8c4844ff","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0f2ac82a-5815-5de8-abd9-6ddf8c4844ff/attachment.md","path":"references/features-forms-validation.md","size":4963,"sha256":"c8a151577263d10c2442c61f871299984b3c866ed8205ff4c9db5479dfa25d0b","contentType":"text/markdown; charset=utf-8"},{"id":"ca82d756-d5a7-586a-9fd3-955ebce08cef","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ca82d756-d5a7-586a-9fd3-955ebce08cef/attachment.md","path":"references/features-hero-animations.md","size":4748,"sha256":"00f3f4b050b44353d0ea021d1a45567187ddec9e6a1fc20d25cbc96c6a85e65d","contentType":"text/markdown; charset=utf-8"},{"id":"91a60983-71c8-522e-9791-49eb0ec4cddd","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/91a60983-71c8-522e-9791-49eb0ec4cddd/attachment.md","path":"references/features-http.md","size":3956,"sha256":"fd5e419229131eccdfa1838d768007f70b08a6ec3bb5f17444e213dbb72b55c5","contentType":"text/markdown; charset=utf-8"},{"id":"cdd92e0b-bc63-5156-8bb1-da1b43838492","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/cdd92e0b-bc63-5156-8bb1-da1b43838492/attachment.md","path":"references/features-implicit-animations.md","size":7712,"sha256":"fba031e8e2d71651407a2792081872b6471781f47e8d72b0f15c4d2a0b6686bd","contentType":"text/markdown; charset=utf-8"},{"id":"d988c39a-431b-5a4d-8d53-d1b2467cae36","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d988c39a-431b-5a4d-8d53-d1b2467cae36/attachment.md","path":"references/features-inherited-widget.md","size":3127,"sha256":"77f5d1bf9680af2ecbde7c8c39d147c42387b5c09f05e582616c85a9ececcd84","contentType":"text/markdown; charset=utf-8"},{"id":"3a3fd4dc-b43b-5102-abc3-265b1ea2f2b5","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/3a3fd4dc-b43b-5102-abc3-265b1ea2f2b5/attachment.md","path":"references/features-keys.md","size":3088,"sha256":"f30f26ac6933e26e8d172962364c2310b4716e946c100b48d9b0295b5a64e21b","contentType":"text/markdown; charset=utf-8"},{"id":"7cbef986-6676-5b1c-ad84-f3b65889c4d3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7cbef986-6676-5b1c-ad84-f3b65889c4d3/attachment.md","path":"references/features-lifecycle.md","size":4340,"sha256":"e658ece60a7584ed7a808ceab01fa45a6c596f26074a8cbf8fcb2dd6d3c8e02a","contentType":"text/markdown; charset=utf-8"},{"id":"b625f598-e52d-583e-8af4-a3bad0698d1e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b625f598-e52d-583e-8af4-a3bad0698d1e/attachment.md","path":"references/features-material-3.md","size":3796,"sha256":"06ae44742f8ae92316383610915bf45e204765d7fb8e169562ba732ce45ec2f9","contentType":"text/markdown; charset=utf-8"},{"id":"dcd4b4e2-55d1-5e81-8f5d-182386920e70","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/dcd4b4e2-55d1-5e81-8f5d-182386920e70/attachment.md","path":"references/features-material-app.md","size":4668,"sha256":"dabfff4c6a411bf6bf294ef36038c4f22e42e6116d4e2e2252bb2d87dcc9806d","contentType":"text/markdown; charset=utf-8"},{"id":"034ab00a-7d7a-53aa-8558-8f7f60cb783d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/034ab00a-7d7a-53aa-8558-8f7f60cb783d/attachment.md","path":"references/features-material-components.md","size":4433,"sha256":"fecc10b56520baa6c658a4d301652e12e55d89674e978b53544c5c12124cb684","contentType":"text/markdown; charset=utf-8"},{"id":"6bdf8021-c211-529a-92eb-633e87da61c5","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6bdf8021-c211-529a-92eb-633e87da61c5/attachment.md","path":"references/features-named-routes.md","size":4910,"sha256":"4a9eaae17c3eb913038b1dc9027952d83e3bbf75a2419766c17253b0391c2056","contentType":"text/markdown; charset=utf-8"},{"id":"6f1e38bc-414b-5964-9703-081df672472c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6f1e38bc-414b-5964-9703-081df672472c/attachment.md","path":"references/features-navigation.md","size":5099,"sha256":"b7531d03ce4316e03386805ab5b5804a47bb3b1bcdeefc40ff43adc59c3a17e3","contentType":"text/markdown; charset=utf-8"},{"id":"10a84ad8-87d9-5195-a72a-1d227b1114b4","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/10a84ad8-87d9-5195-a72a-1d227b1114b4/attachment.md","path":"references/features-platform-channels.md","size":5153,"sha256":"e2f1cff14aed13bc5230e2e95761b38e53ef435bf091a955243e8eab97d2b732","contentType":"text/markdown; charset=utf-8"},{"id":"86aa35e1-1247-5f62-b0b5-43c0853f513e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/86aa35e1-1247-5f62-b0b5-43c0853f513e/attachment.md","path":"references/features-platform-views.md","size":3713,"sha256":"962fc72642599bac70bed68e1dc050e49ae0d3bd5666704a694c484300d0880e","contentType":"text/markdown; charset=utf-8"},{"id":"50029ff6-d9ec-57e9-a2b0-71c8676e4de0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/50029ff6-d9ec-57e9-a2b0-71c8676e4de0/attachment.md","path":"references/features-pop-scope.md","size":2190,"sha256":"7537cfba4bcfb2e14a29906af0f74f2907d68b5ba8b25c84aa8d85dc2ede1475","contentType":"text/markdown; charset=utf-8"},{"id":"74614d5b-34db-58e8-b259-978587090fb0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/74614d5b-34db-58e8-b259-978587090fb0/attachment.md","path":"references/features-responsive.md","size":3158,"sha256":"c8d019bbfe7a0f5230471467b26c36563eae6e363b559655327bfd41bf619708","contentType":"text/markdown; charset=utf-8"},{"id":"46ee7b04-5277-5fef-9834-4ff7d04ca2e0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/46ee7b04-5277-5fef-9834-4ff7d04ca2e0/attachment.md","path":"references/features-router.md","size":3109,"sha256":"a58d5db9c0b1517ab12c157a1e4f72880010e91409c39ce685d2c8af8c642118","contentType":"text/markdown; charset=utf-8"},{"id":"7443012d-d9e5-559c-b9fd-9eadb0a16f57","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7443012d-d9e5-559c-b9fd-9eadb0a16f57/attachment.md","path":"references/features-scroll-controller.md","size":2998,"sha256":"562e530898e0112739dff04258849b72ddd7cded083dbda30bd908ef6c8d8160","contentType":"text/markdown; charset=utf-8"},{"id":"d30ed1cc-6009-5c60-9b85-0bed501b25c6","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d30ed1cc-6009-5c60-9b85-0bed501b25c6/attachment.md","path":"references/features-slivers.md","size":3568,"sha256":"d6787dbc86b69ac194dcadf6897bac162b07e903332d3a8f0d9a5e34d730c306","contentType":"text/markdown; charset=utf-8"},{"id":"6bada6b0-ce66-5675-84b4-ce9dd31bfd47","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6bada6b0-ce66-5675-84b4-ce9dd31bfd47/attachment.md","path":"references/layout-container.md","size":5283,"sha256":"e131142411abfad5d44f3bb3783009e19252829b2b55fd9603742d57ef423528","contentType":"text/markdown; charset=utf-8"},{"id":"a9e206dd-f84e-5139-9064-543ec1b2de61","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a9e206dd-f84e-5139-9064-543ec1b2de61/attachment.md","path":"references/layout-flex.md","size":5362,"sha256":"e96cae193316f05488c71470dbeeac34dd35c287d8c2a3edf59bf8283dd37c8d","contentType":"text/markdown; charset=utf-8"},{"id":"7db7292e-499e-56f5-97b7-cd4e27aaadc3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7db7292e-499e-56f5-97b7-cd4e27aaadc3/attachment.md","path":"references/layout-lists.md","size":5459,"sha256":"5e0d1fd4ac4d09ef20f780af74518b9e704bdd8d0eec7c750043c787012e7c3f","contentType":"text/markdown; charset=utf-8"},{"id":"47e307b0-6dde-5999-840f-e5799db56b28","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/47e307b0-6dde-5999-840f-e5799db56b28/attachment.md","path":"references/layout-stack.md","size":4427,"sha256":"a5c13505d01ed9b68d92f963e324e35161ae309baad63b6918ca889f48a427df","contentType":"text/markdown; charset=utf-8"},{"id":"6ce1e790-e8fc-5fec-947c-4e99f2eb94fd","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6ce1e790-e8fc-5fec-947c-4e99f2eb94fd/attachment.md","path":"references/widgets-async.md","size":4617,"sha256":"580607ba135413f2fe1e0cb8083db10cde44f0f4cc856cf7a8e89b28952d9769","contentType":"text/markdown; charset=utf-8"},{"id":"c4443276-b629-5c17-bb76-cb96c77f4315","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c4443276-b629-5c17-bb76-cb96c77f4315/attachment.md","path":"references/widgets-buttons.md","size":3000,"sha256":"a5d718551abab207ff18b93c42e1347d448331fbeb3d558306919bb750f0c825","contentType":"text/markdown; charset=utf-8"},{"id":"d8203b01-2f7c-5d63-865d-a14a2359f5f0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d8203b01-2f7c-5d63-865d-a14a2359f5f0/attachment.md","path":"references/widgets-dismissible.md","size":4048,"sha256":"e5cf8f08a2f633a3ec8a71d1a1df3b9fa9c738beeaa10f383caf4271de2a3b14","contentType":"text/markdown; charset=utf-8"},{"id":"a3fc3289-4a46-548f-b46a-2dc4d8acc604","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a3fc3289-4a46-548f-b46a-2dc4d8acc604/attachment.md","path":"references/widgets-icons.md","size":3334,"sha256":"30beb39aaaf070aba3f2fbb869c5bc21b8043e3c52a465b97302b16c107445f1","contentType":"text/markdown; charset=utf-8"},{"id":"72ec5bf5-0a95-50ba-9e50-aaa830b632ae","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/72ec5bf5-0a95-50ba-9e50-aaa830b632ae/attachment.md","path":"references/widgets-images.md","size":5134,"sha256":"2c2e02262f612f8fd3cfae9e0d00e930ab6f11ee4986d091e91c26db303850f4","contentType":"text/markdown; charset=utf-8"},{"id":"1e4cb672-9bb6-567c-b279-2434db50fad8","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/1e4cb672-9bb6-567c-b279-2434db50fad8/attachment.md","path":"references/widgets-input.md","size":4178,"sha256":"5d0240621fe1db344825eb1e11a5711666b444be15ce3ecf76013780ed4d1fff","contentType":"text/markdown; charset=utf-8"},{"id":"6e671283-db8a-5723-be7f-0071944af295","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6e671283-db8a-5723-be7f-0071944af295/attachment.md","path":"references/widgets-pageview.md","size":3603,"sha256":"cf0a58aaabebf9a7a88f46aea8d000e0702169e74929de97bb6811acde420103","contentType":"text/markdown; charset=utf-8"},{"id":"5dfabcc9-df11-597d-9482-35d53603d04a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5dfabcc9-df11-597d-9482-35d53603d04a/attachment.md","path":"references/widgets-refresh-indicator.md","size":2608,"sha256":"1e3416b1fb81b09e155b2f74e3192118f88c499be4ea3dd6ed1a382ac4a0822f","contentType":"text/markdown; charset=utf-8"},{"id":"defd21e7-eeae-54fc-897f-c116bef62614","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/defd21e7-eeae-54fc-897f-c116bef62614/attachment.md","path":"references/widgets-tabs.md","size":3577,"sha256":"ce7fff4da5ac22631146b72d43bef3b2208aa4a801a7a20580b557c7e55d90e9","contentType":"text/markdown; charset=utf-8"},{"id":"c501e1b4-219d-56ea-b0a7-278e125986a3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c501e1b4-219d-56ea-b0a7-278e125986a3/attachment.md","path":"references/widgets-text.md","size":3981,"sha256":"05afe0f6ccfbb37079fa08fc769164b5698bf7baa749094260bbbe31dc2303f3","contentType":"text/markdown; charset=utf-8"},{"id":"3f505df3-343c-5070-8c53-353ed39c264d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/3f505df3-343c-5070-8c53-353ed39c264d/attachment.md","path":"references/widgets-value-listenable.md","size":2390,"sha256":"c6cdc4fea59323d4583fd8421c7ea2d1adf464538847ebb9953b37ff5c0017d7","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"046f9d526c5480d800ac45ce21fdc732ba07d6ccb62b310bdfcb70079ae5b658","attachment_count":51,"text_attachments":51,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/flutter/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"web-development","metadata":{"author":"hairy","source":"Generated from https://github.com/flutter/flutter, scripts located at https://github.com/hairyf/skills","version":"2026.1.31"},"import_tag":"clean-skills-v1","description":"Flutter framework for building beautiful, fast user experiences for mobile, web, and desktop from a single codebase. Use when building Flutter apps, working with widgets, state management, navigation, animations, or Material Design components."}},"renderedAt":1782981762509}

Flutter The skill is based on Flutter framework, generated at 2026-01-31. Flutter is Google's SDK for crafting beautiful, fast user experiences for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Flutter uses Dart as its programming language and follows a widget-based architecture where everything is a widget. The framework provides hot reload for fast development cycles, a rich set of Material Design and Cupertino widgets, and excellent performance through compiled code.…