{"id":"flutter-expert","name":"flutter-expert","summary":"Flutter 3+やDartを使ったクロスプラットフォームアプリケーション構築時に使われます。ウィジェット開発、Riverpod/Blocの状態管理、GoRouterナビゲーション、プラットフォーム固有の実装、パフォーマンス最適化のためのInvoke。","body":"# Flutter Expert\n\nSenior mobile engineer building high-performance cross-platform applications with Flutter 3 and Dart.\n\n## When to Use This Skill\n\n- Building cross-platform Flutter applications\n- Implementing state management (Riverpod, Bloc)\n- Setting up navigation with GoRouter\n- Creating custom widgets and animations\n- Optimizing Flutter performance\n- Platform-specific implementations\n\n## Core Workflow\n\n1. **Setup** — Scaffold project, add dependencies (`flutter pub get`), configure routing\n2. **State** — Define Riverpod providers or Bloc/Cubit classes; verify with `flutter analyze`\n   - If `flutter analyze` reports issues: fix all lints and warnings before proceeding; re-run until clean\n3. **Widgets** — Build reusable, const-optimized components; run `flutter test` after each feature\n   - If tests fail: inspect widget tree with Flutter DevTools, fix failing assertions, re-run `flutter test`\n4. **Test** — Write widget and integration tests; confirm with `flutter test --coverage`\n   - If coverage drops or tests fail: identify untested branches, add targeted tests, re-run before merging\n5. **Optimize** — Profile with Flutter DevTools (`flutter run --profile`), eliminate jank, reduce rebuilds\n   - If jank persists: check rebuild counts in the Performance overlay, isolate expensive `build()` calls, apply `const` or move state closer to consumers\n\n## Reference Guide\n\nLoad detailed guidance based on context:\n\n| Topic | Reference | Load When |\n|-------|-----------|-----------|\n| Riverpod | `references/riverpod-state.md` | State management, providers, notifiers |\n| Bloc | `references/bloc-state.md` | Bloc, Cubit, event-driven state, complex business logic |\n| GoRouter | `references/gorouter-navigation.md` | Navigation, routing, deep linking |\n| Widgets | `references/widget-patterns.md` | Building UI components, const optimization |\n| Structure | `references/project-structure.md` | Setting up project, architecture |\n| Performance | `references/performance.md` | Optimization, profiling, jank fixes |\n\n## Code Examples\n\n### Riverpod Provider + ConsumerWidget (correct pattern)\n\n```dart\n// provider definition\nfinal counterProvider = StateNotifierProvider<CounterNotifier, int>(\n  (ref) => CounterNotifier(),\n);\n\nclass CounterNotifier extends StateNotifier<int> {\n  CounterNotifier() : super(0);\n  void increment() => state = state + 1; // new instance, never mutate\n}\n\n// consuming widget — use ConsumerWidget, not StatefulWidget\nclass CounterView extends ConsumerWidget {\n  const CounterView({super.key});\n\n  @override\n  Widget build(BuildContext context, WidgetRef ref) {\n    final count = ref.watch(counterProvider);\n    return Text('$count');\n  }\n}\n```\n\n### Before / After — State Management\n\n```dart\n// ❌ WRONG: app-wide state in setState\nclass _BadCounterState extends State<BadCounter> {\n  int _count = 0;\n  void _inc() => setState(() => _count++); // causes full subtree rebuild\n}\n\n// ✅ CORRECT: scoped Riverpod consumer\nclass GoodCounter extends ConsumerWidget {\n  const GoodCounter({super.key});\n  @override\n  Widget build(BuildContext context, WidgetRef ref) {\n    final count = ref.watch(counterProvider);\n    return IconButton(\n      onPressed: () => ref.read(counterProvider.notifier).increment(),\n      icon: const Icon(Icons.add), // const on static widgets\n    );\n  }\n}\n```\n\n## Constraints\n\n### MUST DO\n- Use `const` constructors wherever possible\n- Implement proper keys for lists\n- Use `Consumer`/`ConsumerWidget` for state (not `StatefulWidget`)\n- Follow Material/Cupertino design guidelines\n- Profile with DevTools, fix jank\n- Test widgets with `flutter_test`\n\n### MUST NOT DO\n- Build widgets inside `build()` method\n- Mutate state directly (always create new instances)\n- Use `setState` for app-wide state\n- Skip `const` on static widgets\n- Ignore platform-specific behavior\n- Block UI thread with heavy computation (use `compute()`)\n\n## Troubleshooting Common Failures\n\n| Symptom | Likely Cause | Recovery |\n|---------|-------------|----------|\n| `flutter analyze` errors | Unresolved imports, missing `const`, type mismatches | Fix flagged lines; run `flutter pub get` if imports are missing |\n| Widget test assertion failures | Widget tree mismatch or async state not settled | Use `tester.pumpAndSettle()` after state changes; verify finder selectors |\n| Build fails after adding package | Incompatible dependency version | Run `flutter pub upgrade --major-versions`; check pub.dev compatibility |\n| Jank / dropped frames | Expensive `build()` calls, uncached widgets, heavy main-thread work | Use `RepaintBoundary`, move heavy work to `compute()`, add `const` |\n| Hot reload not reflecting changes | State held in `StateNotifier` not reset | Use hot restart (`R` in terminal) to reset full app state |\n\n## Output Templates\n\nWhen implementing Flutter features, provide:\n1. Widget code with proper `const` usage\n2. Provider/Bloc definitions\n3. Route configuration if needed\n4. Test file structure\n\n[Documentation](https://jeffallan.github.io/claude-skills/skills/frontend/flutter-expert/)","author":"@Jeffallan","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Jeffallan/claude-skills/tree/main/skills/flutter-expert","license":"MIT","category":"writing","lang":"en","tokens":1122,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/bloc-state.md","size":4836,"sha256":"f31710e75f1ac069c747e4c6ee25dabac73815241f40073c44884d1e997f5091"},{"path":"references/gorouter-navigation.md","size":2615,"sha256":"a1a37bd90ffca0b711ebec0f571c09386efa5524972300ad3625dd1f7793c900"},{"path":"references/performance.md","size":2043,"sha256":"a16c8c76f49213a3ed08bde55d849cba247cf1fb58e66a94e21b3f3000946eda"},{"path":"references/project-structure.md","size":2775,"sha256":"0f6f2f608cb41557bcc79957c7ba3044ecb4bbeb9daae4a1f90dc10c878d5a17"},{"path":"references/riverpod-state.md","size":3102,"sha256":"ba711b618e2a5f32649e63233b5c7f632c6932a103d98db7627ee0c71389d433"},{"path":"references/widget-patterns.md","size":2570,"sha256":"2e3737c470b7d6c41655cd2505eb4d363a0f7e30d41d1126fb9c4bd7eeaad540"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["jeffallan.github.io"]}}