Claude-skill-registry flutter-development
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/flutter-development" ~/.claude/skills/majiayu000-claude-skill-registry-flutter-development && rm -rf "$T"
manifest:
skills/data/flutter-development/SKILL.mdsource content
Flutter Development
Overview
Create high-performance, visually stunning mobile applications using Flutter with Dart language. Master widget composition, state management patterns, navigation, and API integration.
When to Use
- Building iOS and Android apps with native performance
- Designing custom UIs with Flutter's widget system
- Implementing complex animations and visual effects
- Rapid app development with hot reload
- Creating consistent UX across platforms
Instructions
1. Project Structure & Navigation
// pubspec.yaml name: my_flutter_app version: 1.0.0 dependencies: flutter: sdk: flutter provider: ^6.0.0 http: ^1.1.0 go_router: ^12.0.0 // main.dart with GoRouter navigation import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp.router( title: 'Flutter App', theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true), routerConfig: _router, ); } } final GoRouter _router = GoRouter( routes: <RouteBase>[ GoRoute( path: '/', builder: (context, state) => const HomeScreen(), routes: [ GoRoute( path: 'details/:id', builder: (context, state) => DetailsScreen( itemId: state.pathParameters['id']! ), ), ], ), GoRoute( path: '/profile', builder: (context, state) => const ProfileScreen(), ), ], );
2. State Management with Provider
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class User { final String id; final String name; final String email; User({required this.id, required this.name, required this.email}); factory User.fromJson(Map<String, dynamic> json) { return User( id: json['id'], name: json['name'], email: json['email'], ); } } class UserProvider extends ChangeNotifier { User? _user; bool _isLoading = false; String? _error; User? get user => _user; bool get isLoading => _isLoading; String? get error => _error; Future<void> fetchUser(String userId) async { _isLoading = true; _error = null; notifyListeners(); try { final response = await http.get( Uri.parse('https://api.example.com/users/$userId'), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { _user = User.fromJson(jsonDecode(response.body)); } else { _error = 'Failed to fetch user'; } } catch (e) { _error = 'Error: ${e.toString()}'; } finally { _isLoading = false; notifyListeners(); } } void logout() { _user = null; notifyListeners(); } } class ItemsProvider extends ChangeNotifier { List<Map<String, dynamic>> _items = []; List<Map<String, dynamic>> get items => _items; Future<void> fetchItems() async { try { final response = await http.get( Uri.parse('https://api.example.com/items'), ); if (response.statusCode == 200) { _items = List<Map<String, dynamic>>.from( jsonDecode(response.body) as List ); notifyListeners(); } } catch (e) { print('Error fetching items: $e'); } } }
3. Screens with Provider Integration
class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override void initState() { super.initState(); Future.microtask(() { Provider.of<ItemsProvider>(context, listen: false).fetchItems(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Home Feed')), body: Consumer<ItemsProvider>( builder: (context, itemsProvider, child) { if (itemsProvider.items.isEmpty) { return const Center(child: Text('No items found')); } return ListView.builder( itemCount: itemsProvider.items.length, itemBuilder: (context, index) { final item = itemsProvider.items[index]; return ItemCard(item: item); }, ); }, ), ); } } class ItemCard extends StatelessWidget { final Map<String, dynamic> item; const ItemCard({required this.item, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.all(8), child: ListTile( title: Text(item['title'] ?? 'Untitled'), subtitle: Text(item['description'] ?? ''), trailing: const Icon(Icons.arrow_forward), onTap: () => context.go('/details/${item['id']}'), ), ); } } class DetailsScreen extends StatelessWidget { final String itemId; const DetailsScreen({required this.itemId, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Details')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Item ID: $itemId', style: const TextStyle(fontSize: 18)), const SizedBox(height: 16), ElevatedButton( onPressed: () => context.pop(), child: const Text('Go Back'), ), ], ), ), ); } } class ProfileScreen extends StatelessWidget { const ProfileScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Profile')), body: Consumer<UserProvider>( builder: (context, userProvider, child) { if (userProvider.isLoading) { return const Center(child: CircularProgressIndicator()); } if (userProvider.error != null) { return Center(child: Text('Error: ${userProvider.error}')); } final user = userProvider.user; if (user == null) { return const Center(child: Text('No user data')); } return Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Name: ${user.name}', style: const TextStyle(fontSize: 18)), Text('Email: ${user.email}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 16), ElevatedButton( onPressed: () => userProvider.logout(), child: const Text('Logout'), ), ], ), ); }, ), ); } }
Best Practices
✅ DO
- Use widgets for every UI element
- Implement proper state management
- Use const constructors where possible
- Dispose resources in state lifecycle
- Test on multiple device sizes
- Use meaningful widget names
- Implement error handling
- Use responsive design patterns
- Test on both iOS and Android
- Document custom widgets
❌ DON'T
- Build entire screens in build() method
- Use setState for complex state logic
- Make network calls in build()
- Ignore platform differences
- Create overly nested widget trees
- Hardcode strings
- Ignore performance warnings
- Skip testing
- Forget to handle edge cases
- Deploy without thorough testing