dart-expert

Dart & Flutter Expert

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 "dart-expert" with this command: npx skills add personamanagmentlayer/pcl/personamanagmentlayer-pcl-dart-expert

Dart & Flutter Expert

Expert guidance for Dart programming, Flutter framework, mobile development, and cross-platform applications.

Core Concepts

Dart Language

  • Strong typing with type inference

  • Async/await and Futures

  • Streams

  • Mixins and extensions

  • Null safety

  • Collections

Flutter Framework

  • Widgets (Stateless & Stateful)

  • State management (Provider, Riverpod, Bloc)

  • Navigation and routing

  • Material and Cupertino design

  • Responsive layouts

  • Platform integration

Dart Fundamentals

// Variables and types var name = 'John'; // Type inference String explicitType = 'Explicit'; final constantValue = 42; // Runtime constant const compileConstant = 'Compile-time';

// Null safety String? nullableString; String nonNullable = 'Never null';

// Late initialization late String lateInit;

// Collections List<String> names = ['Alice', 'Bob', 'Charlie']; Map<String, int> ages = {'Alice': 25, 'Bob': 30}; Set<int> uniqueNumbers = {1, 2, 3, 3}; // {1, 2, 3}

// Functions int add(int a, int b) => a + b;

// Named parameters void createUser({ required String name, int age = 18, String? email, }) { print('Creating user: $name, age: $age'); }

// Classes class User { final String id; final String name; int age;

User({ required this.id, required this.name, this.age = 0, });

// Named constructor User.guest() : this(id: 'guest', name: 'Guest');

// Methods void celebrateBirthday() { age++; }

@override String toString() => 'User($name, $age)'; }

// Mixins mixin Loggable { void log(String message) { print('[${DateTime.now()}] $message'); } }

class LoggableUser extends User with Loggable { LoggableUser({required String id, required String name}) : super(id: id, name: name); }

// Extensions extension StringExtensions on String { bool get isValidEmail => contains('@') && contains('.'); String capitalize() => '${this[0].toUpperCase()}${substring(1)}'; }

Async Programming

import 'dart:async';

// Future Future<String> fetchUser(String id) async { await Future.delayed(Duration(seconds: 1)); return 'User $id'; }

// Error handling Future<User?> fetchUserSafely(String id) async { try { final user = await fetchUser(id); return User(id: id, name: user); } catch (e) { print('Error: $e'); return null; } }

// Multiple futures Future<void> fetchMultiple() async { final results = await Future.wait([ fetchUser('1'), fetchUser('2'), fetchUser('3'), ]); print(results); }

// Streams Stream<int> countStream() async* { for (int i = 1; i <= 5; i++) { await Future.delayed(Duration(seconds: 1)); yield i; } }

// Listen to stream void listenToStream() { countStream().listen( (data) => print('Received: $data'), onError: (error) => print('Error: $error'), onDone: () => print('Done'), ); }

// Stream transformations Stream<String> transformedStream() { return countStream() .where((n) => n % 2 == 0) .map((n) => 'Number: $n') .take(3); }

// StreamController class Counter { final _controller = StreamController<int>();

Stream<int> get stream => _controller.stream;

void increment(int value) { _controller.add(value); }

void dispose() { _controller.close(); } }

Flutter Widgets

import 'package:flutter/material.dart';

// Stateless Widget class UserCard extends StatelessWidget { final User user;

const UserCard({Key? key, required this.user}) : super(key: key);

@override Widget build(BuildContext context) { return Card( child: ListTile( title: Text(user.name), subtitle: Text('Age: ${user.age}'), trailing: Icon(Icons.arrow_forward), ), ); } }

// Stateful Widget class CounterWidget extends StatefulWidget { const CounterWidget({Key? key}) : super(key: key);

@override State<CounterWidget> createState() => _CounterWidgetState(); }

class _CounterWidgetState extends State<CounterWidget> { int _counter = 0;

void _incrementCounter() { setState(() { _counter++; }); }

@override Widget build(BuildContext context) { return Column( children: [ Text('Counter: $_counter'), ElevatedButton( onPressed: _incrementCounter, child: Text('Increment'), ), ], ); } }

// Layout class UserListScreen extends StatelessWidget { final List<User> users;

const UserListScreen({Key? key, required this.users}) : super(key: key);

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Users'), actions: [ IconButton( icon: Icon(Icons.add), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => AddUserScreen()), ), ), ], ), body: ListView.builder( itemCount: users.length, itemBuilder: (context, index) { return UserCard(user: users[index]); }, ), ); } }

State Management (Provider)

import 'package:provider/provider.dart';

// State class class UserProvider extends ChangeNotifier { List<User> _users = [];

List<User> get users => _users;

Future<void> fetchUsers() async { _users = await api.getUsers(); notifyListeners(); }

void addUser(User user) { _users.add(user); notifyListeners(); }

void removeUser(String id) { _users.removeWhere((user) => user.id == id); notifyListeners(); } }

// Setup provider void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: () => UserProvider()), ChangeNotifierProvider(create: () => AuthProvider()), ], child: MyApp(), ), ); }

// Consume provider class UserList extends StatelessWidget { @override Widget build(BuildContext context) { final userProvider = Provider.of<UserProvider>(context);

return ListView.builder(
  itemCount: userProvider.users.length,
  itemBuilder: (context, index) {
    final user = userProvider.users[index];
    return ListTile(
      title: Text(user.name),
      trailing: IconButton(
        icon: Icon(Icons.delete),
        onPressed: () => userProvider.removeUser(user.id),
      ),
    );
  },
);

} }

// Consumer widget class UserCounter extends StatelessWidget { @override Widget build(BuildContext context) { return Consumer<UserProvider>( builder: (context, userProvider, child) { return Text('Total users: ${userProvider.users.length}'); }, ); } }

Navigation

// Basic navigation Navigator.push( context, MaterialPageRoute(builder: (context) => DetailScreen()), );

// Named routes MaterialApp( routes: { '/': (context) => HomeScreen(), '/details': (context) => DetailScreen(), '/settings': (context) => SettingsScreen(), }, );

Navigator.pushNamed(context, '/details');

// Pass arguments Navigator.pushNamed( context, '/details', arguments: {'userId': '123'}, );

// Get arguments final args = ModalRoute.of(context)!.settings.arguments as Map;

// Return data final result = await Navigator.push( context, MaterialPageRoute(builder: (_) => SelectionScreen()), );

// Pop with result Navigator.pop(context, selectedValue);

HTTP and API

import 'package:http/http.dart' as http; import 'dart:convert';

class ApiService { final String baseUrl = 'https://api.example.com';

Future<List<User>> fetchUsers() async { final response = await http.get(Uri.parse('$baseUrl/users'));

if (response.statusCode == 200) {
  final List&#x3C;dynamic> data = json.decode(response.body);
  return data.map((json) => User.fromJson(json)).toList();
} else {
  throw Exception('Failed to load users');
}

}

Future<User> createUser(User user) async { final response = await http.post( Uri.parse('$baseUrl/users'), headers: {'Content-Type': 'application/json'}, body: json.encode(user.toJson()), );

if (response.statusCode == 201) {
  return User.fromJson(json.decode(response.body));
} else {
  throw Exception('Failed to create user');
}

} }

// Model with JSON serialization 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'], ); }

Map<String, dynamic> toJson() { return { 'id': id, 'name': name, 'email': email, }; } }

Best Practices

Dart

  • Use const constructors when possible

  • Leverage null safety

  • Use final for immutable values

  • Prefer async/await over .then()

  • Use extensions for utility methods

  • Follow Effective Dart guidelines

Flutter

  • Keep widgets small and focused

  • Use const widgets for optimization

  • Avoid rebuilding entire trees

  • Implement proper state management

  • Handle errors gracefully

  • Test widgets thoroughly

  • Use keys when needed

Performance

  • Use ListView.builder for long lists

  • Implement pagination

  • Cache network images

  • Minimize widget rebuilds

  • Use const constructors

  • Profile app performance

  • Lazy load resources

Anti-Patterns

❌ Large widget trees ❌ State in StatelessWidget ❌ Not disposing controllers ❌ Ignoring null safety ❌ Synchronous I/O in UI ❌ No error handling ❌ Hard-coded strings

Resources

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.

General

finance-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

trading-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

postgresql-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

real-estate-expert

No summary provided by upstream source.

Repository SourceNeeds Review