flutter

Cross-platform UI framework for mobile, web, and desktop.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "flutter" with this command: npx skills add g1joshi/agent-skills/g1joshi-agent-skills-flutter

Flutter

Cross-platform UI framework for mobile, web, and desktop.

When to Use

  • Cross-platform mobile apps

  • Single codebase for iOS/Android

  • Custom UI with animations

  • Rapid prototyping

Quick Start

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget { const MyApp({super.key});

@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('My App')), body: const Center(child: Text('Hello Flutter!')), ), ); } }

Core Concepts

Widgets & State

class Counter extends StatefulWidget { const Counter({super.key});

@override State<Counter> createState() => _CounterState(); }

class _CounterState extends State<Counter> { int _count = 0;

@override Widget build(BuildContext context) { return Column( children: [ Text('Count: $_count'), ElevatedButton( onPressed: () => setState(() => _count++), child: const Text('Increment'), ), ], ); } }

Riverpod State Management

import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateNotifierProvider<CounterNotifier, int>( (ref) => CounterNotifier(), );

class CounterNotifier extends StateNotifier<int> { CounterNotifier() : super(0);

void increment() => state++; }

// Usage class MyWidget extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider); return Text('Count: $count'); } }

Common Patterns

Navigation with GoRouter

final router = GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => const HomeScreen(), routes: [ GoRoute( path: 'user/:id', builder: (context, state) => UserScreen( id: state.pathParameters['id']!, ), ), ], ), ], );

// Navigate context.go('/user/123'); context.push('/user/123');

Async Data

final userProvider = FutureProvider.autoDispose.family<User, String>( (ref, userId) async { return ref.read(apiProvider).fetchUser(userId); }, );

// In widget ref.watch(userProvider(userId)).when( data: (user) => UserCard(user: user), loading: () => const CircularProgressIndicator(), error: (error, stack) => Text('Error: $error'), );

Best Practices

Do:

  • Use const constructors

  • Prefer StatelessWidget

  • Use Riverpod for state

  • Follow widget composition

Don't:

  • Put logic in build methods

  • Use setState for global state

  • Create deep widget trees

  • Ignore key parameters

Troubleshooting

Issue Cause Solution

Widget not updating Missing setState Use proper state management

Overflow error Unbounded size Add constraints

Hot reload fails State corruption Hot restart

References

  • Flutter Documentation

  • Riverpod Documentation

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

template

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

mariadb

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

claude

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

javascript

No summary provided by upstream source.

Repository SourceNeeds Review