Ejemplos de Dart

Ejemplos esenciales de programación Dart y fundamentos de desarrollo Flutter

💻 Hola Mundo en Dart dart

🟢 simple

Programa Hola Mundo básico y ejemplos de sintaxis fundamental

⏱️ 15 min 🏷️ dart, programming, beginner, flutter
Prerequisites: Basic programming concepts
// Dart Hello World Examples

// 1. Basic Hello World
void main() {
  print('Hello, World!');
}

// 2. Hello World with variables
void main() {
  String message = 'Hello, World!';
  print(message);
}

// 3. Hello World with function
String sayHello() {
  return 'Hello, World!';
}

void main() {
  print(sayHello());
}

// 4. Hello World with function parameters
String greet(String name) {
  return 'Hello, $name!';
}

void main() {
  print(greet('World'));
  print(greet('Dart'));
  print(greet('Flutter'));
}

// 5. Hello World with class
class Greeter {
  String message;

  Greeter([this.message = 'Hello, World!']);

  String greet() {
    return message;
  }
}

void main() {
  var greeter = Greeter();
  print(greeter.greet());

  var customGreeter = Greeter('Hello from custom class!');
  print(customGreeter.greet());
}

// 6. Hello World with user input
import 'dart:io';

void main() {
  stdout.write('Enter your name: ');
  String? name = stdin.readLineSync();

  if (name != null && name.isNotEmpty) {
    print('Hello, $name!');
  } else {
    print('Hello, Anonymous!');
  }
}

// 7. Hello World multiple times
void main() {
  for (int i = 0; i < 5; i++) {
    print('Hello, World! ${i + 1}');
  }
}

// 8. Hello World with list
void main() {
  List<String> greetings = ['Hello', 'Bonjour', 'Hola', 'Ciao', 'こんにちは'];

  for (String greeting in greetings) {
    print('$greeting, World!');
  }
}

// 9. Hello World with map
void main() {
  Map<String, String> greetings = {
    'en': 'Hello',
    'es': 'Hola',
    'fr': 'Bonjour',
    'de': 'Hallo',
    'ja': 'こんにちは'
  };

  greetings.forEach((lang, greeting) {
    print('$greeting, World! ($lang)');
  });
}

// 10. Hello World with future (async)
import 'dart:async';

Future<String> getAsyncGreeting() async {
  // Simulate a delay
  await Future.delayed(Duration(seconds: 1));
  return 'Hello, Async World!';
}

void main() async {
  print('Starting async operation...');
  String greeting = await getAsyncGreeting();
  print(greeting);
}

// Basic data types examples
void main() {
  // Numbers
  int integer = 42;
  double doubleNumber = 3.14;

  // String
  String text = 'Dart';

  // Boolean
  bool isAwesome = true;

  // Lists
  List<int> numbers = [1, 2, 3, 4, 5];
  List<String> fruits = ['apple', 'banana', 'cherry'];

  // Maps
  Map<String, int> scores = {
    'math': 95,
    'science': 88,
    'english': 92
  };

  print('Integer: $integer, Type: ${integer.runtimeType}');
  print('Double: $doubleNumber, Type: ${doubleNumber.runtimeType}');
  print('String: $text, Type: ${text.runtimeType}');
  print('Boolean: $isAwesome, Type: ${isAwesome.runtimeType}');
  print('List: $numbers, Type: ${numbers.runtimeType}');
  print('Map: $scores, Type: ${scores.runtimeType}');
}

// Control flow examples
void main() {
  int age = 18;

  // If-else
  if (age >= 18) {
    print('You are an adult');
  } else {
    print('You are a minor');
  }

  // Switch
  String grade = 'A';
  switch (grade) {
    case 'A':
      print('Excellent!');
      break;
    case 'B':
      print('Good!');
      break;
    case 'C':
      print('Fair');
      break;
    default:
      print('Needs improvement');
  }

  // Loops
  List<String> fruits = ['apple', 'banana', 'cherry'];
  for (String fruit in fruits) {
    print('I like $fruit');
  }

  // While loop
  int count = 0;
  while (count < 3) {
    print('Count: $count');
    count++;
  }
}

// String interpolation and formatting
void main() {
  String name = 'Dart';
  int version = 3;
  double rating = 4.5;

  print('Language: $name');
  print('Version: $version');
  print('Rating: $rating');
  print('Formatted: Language $name version $version has rating $rating');

  // More complex interpolation
  String message = '$name is awesome! It's version $version.';
  print(message);
}

// Null safety examples (Dart 2.12+)
void main() {
  // Non-nullable string
  String nonNullString = 'This cannot be null';

  // Nullable string
  String? nullableString;

  print('Non-null string: $nonNullString');
  print('Nullable string: ${nullableString ?? "Default value"}');

  // Null assertion
  nullableString = 'Now it has a value';
  print('After assignment: ${nullableString!}');

  // Null-aware operators
  String? nullString;
  String result = nullString ?? 'Default';
  print('Result: $result');
}

💻 Programación Asíncrona Dart dart

🟡 intermediate ⭐⭐⭐

Patrones de programación asíncrona moderna con Future, Stream y async/await

⏱️ 25 min 🏷️ dart, async, concurrency, streams, future
Prerequisites: Basic Dart syntax, Understanding of asynchronous programming
// Dart Async Programming Examples

import 'dart:async';
import 'dart:io';
import 'dart:convert';

// 1. Basic Future usage
Future<String> fetchData() async {
  print('Starting to fetch data...');
  await Future.delayed(Duration(seconds: 2));
  return 'Data fetched successfully!';
}

void main() async {
  print('Before fetch');
  String data = await fetchData();
  print('After fetch: $data');
}

// 2. Multiple futures
Future<String> fetchUserData() async {
  await Future.delayed(Duration(seconds: 1));
  return 'User: John Doe';
}

Future<String> fetchPostsData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Posts: [Post1, Post2, Post3]';
}

void main() async {
  print('Fetching user and posts...');

  // Sequential execution
  String user = await fetchUserData();
  String posts = await fetchPostsData();

  print('$user');
  print('$posts');
}

// 3. Parallel futures with Future.wait
Future<String> fetchProfile() async {
  await Future.delayed(Duration(seconds: 1));
  return 'Profile loaded';
}

Future<String> fetchSettings() async {
  await Future.delayed(Duration(seconds: 1));
  return 'Settings loaded';
}

void main() async {
  print('Loading data in parallel...');

  DateTime start = DateTime.now();

  List<String> results = await Future.wait([
    fetchProfile(),
    fetchSettings()
  ]);

  DateTime end = DateTime.now();
  Duration duration = end.difference(start);

  print('Results: $results');
  print('Time taken: ${duration.inMilliseconds}ms');
}

// 4. Error handling in async code
Future<String> riskyOperation() async {
  await Future.delayed(Duration(seconds: 1));

  // Simulate an error
  if (DateTime.now().second % 2 == 0) {
    throw Exception('Something went wrong!');
  }

  return 'Operation successful';
}

void main() async {
  try {
    String result = await riskyOperation();
    print('Result: $result');
  } catch (e) {
    print('Error: $e');
  } finally {
    print('Operation completed');
  }
}

// 5. Timeout handling
Future<String> slowOperation() async {
  await Future.delayed(Duration(seconds: 3));
  return 'Slow operation completed';
}

void main() async {
  try {
    String result = await slowOperation()
        .timeout(Duration(seconds: 2), onTimeout: () {
      return 'Operation timed out';
    });

    print('Result: $result');
  } catch (e) {
    print('Error: $e');
  }
}

// 6. Stream basics
Stream<int> numberStream() async* {
  for (int i = 1; i <= 10; i++) {
    await Future.delayed(Duration(milliseconds: 500));
    yield i;
  }
}

void main() async {
  print('Starting stream...');

  await for (int number in numberStream()) {
    print('Number: $number');
  }

  print('Stream completed');
}

// 7. Stream transformation
Stream<String> textStream() async* {
  List<String> texts = ['Hello', 'World', 'from', 'Dart', 'Streams'];

  for (String text in texts) {
    await Future.delayed(Duration(milliseconds: 300));
    yield text;
  }
}

void main() async {
  // Transform stream
  Stream<int> lengthsStream = textStream()
      .map((text) => text.length)
      .where((length) => length > 3);

  await for (int length in lengthsStream) {
    print('Word length: $length');
  }
}

// 8. Stream controller and broadcast streams
class CounterStream {
  final _controller = StreamController<int>();
  int _counter = 0;

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

  void increment() {
    _counter++;
    _controller.add(_counter);
  }

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

void main() async {
  CounterStream counterStream = CounterStream();

  counterStream.stream.listen(
    (value) => print('Counter: $value'),
    onDone: () => print('Counter stream closed'),
    onError: (error) => print('Error: $error')
  );

  // Increment counter
  for (int i = 0; i < 5; i++) {
    counterStream.increment();
    await Future.delayed(Duration(milliseconds: 500));
  }

  counterStream.dispose();
}

// 9. File I/O with async
Future<void> writeAndReadFile() async {
  String filename = 'test_file.txt';
  String content = 'Hello from Dart async file operations!';

  try {
    // Write to file
    File file = File(filename);
    await file.writeAsString(content);
    print('File written successfully');

    // Read from file
    String readContent = await file.readAsString();
    print('File content: $readContent');

    // Delete file
    await file.delete();
    print('File deleted');
  } catch (e) {
    print('File operation error: $e');
  }
}

void main() async {
  await writeAndReadFile();
}

// 10. HTTP requests with async
import 'package:http/http.dart' as http;

Future<Map<String, dynamic>> fetchUserData(int userId) async {
  try {
    final response = await http.get(
      Uri.parse('https://jsonplaceholder.typicode.com/users/$userId')
    );

    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('Failed to load user data');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

void main() async {
  try {
    Map<String, dynamic> user = await fetchUserData(1);
    print('User: ${user['name']}');
    print('Email: ${user['email']}');
    print('Phone: ${user['phone']}');
  } catch (e) {
    print('Error fetching user: $e');
  }
}

// 11. Async generators and completer
Future<List<String>> fetchMultipleUrls() async {
  List<String> urls = [
    'https://api.github.com/users/dart-lang',
    'https://api.github.com/users/flutter',
  ];

  List<Future<String>> futures = urls.map((url) async {
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      return url;
    }
    throw Exception('Failed to fetch $url');
  }).toList();

  try {
    return await Future.wait(futures);
  } catch (e) {
    print('Some requests failed: $e');
    return [];
  }
}

void main() async {
  List<String> successfulUrls = await fetchMultipleUrls();
  print('Successfully fetched: $successfulUrls');
}

// 12. Async/await with isolated computations
import 'dart:isolate';

Future<int> heavyComputation(int n) async {
  // Simulate heavy computation
  int sum = 0;
  for (int i = 0; i < n; i++) {
    sum += i * i;
  }
  return sum;
}

void main() async {
  print('Starting heavy computation...');

  DateTime start = DateTime.now();
  int result = await heavyComputation(1000000);
  DateTime end = DateTime.now();

  Duration duration = end.difference(start);
  print('Result: $result');
  print('Time taken: ${duration.inMilliseconds}ms');
}

// 13. Stream buffering and debouncing
Stream<String> userInput() async* {
  List<String> inputs = ['d', 'da', 'dar', 'dart', 'dart ', 'dart i', 'dart is', 'dart is a', 'dart is aw', 'dart is awe', 'dart is awes', 'dart is aweso', 'dart is awesom', 'dart is awesome'];

  for (String input in inputs) {
    await Future.delayed(Duration(milliseconds: 200));
    yield input;
  }
}

void main() async {
  // Debounce: wait for user to stop typing
  Stream<String> debouncedStream = userInput()
      .transform(
        StreamTransformer.fromHandlers(
          handleData: (data, sink) {
            // Add custom debouncing logic here if needed
            sink.add(data);
          },
        )
      );

  await for (String input in debouncedStream) {
    if (input.endsWith('awesome')) {
      print('Final input: $input');
      break;
    } else {
      print('Typing: $input');
    }
  }
}

💻 Desarrollo de Widgets Flutter dart

🟡 intermediate ⭐⭐⭐⭐

Construcción de interfaces de usuario con widgets Flutter y gestión de estado

⏱️ 30 min 🏷️ flutter, mobile, ui, widgets, cross-platform
Prerequisites: Dart basics, Understanding of widget concepts, Material Design knowledge
// Flutter Widget Development Examples

import 'package:flutter/material.dart';

// 1. Basic Hello World Flutter App
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Examples',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Hello World'),
        ),
        body: Center(
          child: Text('Hello, Flutter World!'),
        ),
      ),
    );
  }
}

// 2. Counter App with State
void main() {
  runApp(CounterApp());
}

class CounterApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter App',
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends StatefulWidget {
  @override
  _CounterScreenState createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  int _counter = 0;

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

  void _decrementCounter() {
    setState(() {
      if (_counter > 0) _counter--;
    });
  }

  void _resetCounter() {
    setState(() {
      _counter = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Counter App'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Counter Value:',
              style: TextStyle(fontSize: 24),
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            SizedBox(height: 30),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                FloatingActionButton(
                  onPressed: _decrementCounter,
                  child: Icon(Icons.remove),
                  tooltip: 'Decrement',
                ),
                FloatingActionButton(
                  onPressed: _resetCounter,
                  child: Icon(Icons.refresh),
                  tooltip: 'Reset',
                ),
                FloatingActionButton(
                  onPressed: _incrementCounter,
                  child: Icon(Icons.add),
                  tooltip: 'Increment',
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// 3. User Input Form
class UserFormApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'User Form',
      home: UserFormScreen(),
    );
  }
}

class UserFormScreen extends StatefulWidget {
  @override
  _UserFormScreenState createState() => _UserFormScreenState();
}

class _UserFormScreenState extends State<UserFormScreen> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _emailController = TextEditingController();
  final _ageController = TextEditingController();
  String _result = '';

  void _submitForm() {
    if (_formKey.currentState!.validate()) {
      setState(() {
        _result = 'Name: ${_nameController.text}\n'
                  'Email: ${_emailController.text}\n'
                  'Age: ${_ageController.text}';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('User Form'),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                controller: _nameController,
                decoration: InputDecoration(
                  labelText: 'Name',
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your name';
                  }
                  return null;
                },
              ),
              SizedBox(height: 16),
              TextFormField(
                controller: _emailController,
                decoration: InputDecoration(
                  labelText: 'Email',
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your email';
                  }
                  if (!value.contains('@')) {
                    return 'Please enter a valid email';
                  }
                  return null;
                },
              ),
              SizedBox(height: 16),
              TextFormField(
                controller: _ageController,
                decoration: InputDecoration(
                  labelText: 'Age',
                  border: OutlineInputBorder(),
                ),
                keyboardType: TextInputType.number,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your age';
                  }
                  if (int.tryParse(value) == null) {
                    return 'Please enter a valid number';
                  }
                  return null;
                },
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _submitForm,
                child: Text('Submit'),
              ),
              SizedBox(height: 20),
              if (_result.isNotEmpty)
                Container(
                  padding: EdgeInsets.all(16),
                  decoration: BoxDecoration(
                    color: Colors.grey[200],
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Text(_result),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

// 4. List View with Data
class TaskListApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Task List',
      home: TaskListScreen(),
    );
  }
}

class TaskListScreen extends StatefulWidget {
  @override
  _TaskListScreenState createState() => _TaskListScreenState();
}

class _TaskListScreenState extends State<TaskListScreen> {
  final List<Task> _tasks = [
    Task(title: 'Learn Flutter', completed: true),
    Task(title: 'Build an app', completed: false),
    Task(title: 'Deploy to store', completed: false),
    Task(title: 'Write documentation', completed: false),
  ];

  void _toggleTask(int index) {
    setState(() {
      _tasks[index].completed = !_tasks[index].completed;
    });
  }

  void _addTask(String title) {
    setState(() {
      _tasks.add(Task(title: title, completed: false));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Task List'),
      ),
      body: ListView.builder(
        itemCount: _tasks.length,
        itemBuilder: (context, index) {
          return ListTile(
            leading: Checkbox(
              value: _tasks[index].completed,
              onChanged: (bool? value) {
                _toggleTask(index);
              },
            ),
            title: Text(
              _tasks[index].title,
              style: TextStyle(
                decoration: _tasks[index].completed
                    ? TextDecoration.lineThrough
                    : TextDecoration.none,
              ),
            ),
            trailing: IconButton(
              icon: Icon(Icons.delete),
              onPressed: () {
                setState(() {
                  _tasks.removeAt(index);
                });
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          showDialog(
            context: context,
            builder: (context) {
              String newTaskTitle = '';
              return AlertDialog(
                title: Text('Add New Task'),
                content: TextField(
                  onChanged: (value) {
                    newTaskTitle = value;
                  },
                  decoration: InputDecoration(hintText: 'Enter task title'),
                ),
                actions: [
                  TextButton(
                    onPressed: () => Navigator.pop(context),
                    child: Text('Cancel'),
                  ),
                  TextButton(
                    onPressed: () {
                      if (newTaskTitle.isNotEmpty) {
                        _addTask(newTaskTitle);
                      }
                      Navigator.pop(context);
                    },
                    child: Text('Add'),
                  ),
                ],
              );
            },
          );
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class Task {
  String title;
  bool completed;

  Task({required this.title, this.completed = false});
}

// 5. Grid View with Images
class ImageGridApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image Grid',
      home: ImageGridScreen(),
    );
  }
}

class ImageGridScreen extends StatelessWidget {
  final List<String> imageUrls = [
    'https://picsum.photos/200/200?random=1',
    'https://picsum.photos/200/200?random=2',
    'https://picsum.photos/200/200?random=3',
    'https://picsum.photos/200/200?random=4',
    'https://picsum.photos/200/200?random=5',
    'https://picsum.photos/200/200?random=6',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Grid'),
      ),
      body: GridView.builder(
        padding: EdgeInsets.all(8),
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 8,
          mainAxisSpacing: 8,
        ),
        itemCount: imageUrls.length,
        itemBuilder: (context, index) {
          return Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
              boxShadow: [
                BoxShadow(
                  color: Colors.grey.withOpacity(0.3),
                  spreadRadius: 2,
                  blurRadius: 5,
                  offset: Offset(0, 3),
                ),
              ],
            ),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(8),
              child: Image.network(
                imageUrls[index],
                fit: BoxFit.cover,
                loadingBuilder: (context, child, loadingProgress) {
                  if (loadingProgress == null) return child;
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                },
                errorBuilder: (context, error, stackTrace) {
                  return Container(
                    color: Colors.grey[300],
                    child: Icon(Icons.error),
                  );
                },
              ),
            ),
          );
        },
      ),
    );
  }
}

// 6. Tab Bar Navigation
class TabBarApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tab Bar Example',
      home: TabBarScreen(),
    );
  }
}

class TabBarScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Tab Bar Navigation'),
          bottom: TabBar(
            tabs: [
              Tab(icon: Icon(Icons.home), text: 'Home'),
              Tab(icon: Icon(Icons.search), text: 'Search'),
              Tab(icon: Icon(Icons.person), text: 'Profile'),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            HomeTab(),
            SearchTab(),
            ProfileTab(),
          ],
        ),
      ),
    );
  }
}

class HomeTab extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.home, size: 100, color: Colors.blue),
          SizedBox(height: 20),
          Text('Home Tab', style: TextStyle(fontSize: 24)),
          SizedBox(height: 10),
          Text('Welcome to the home screen!'),
        ],
      ),
    );
  }
}

class SearchTab extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(16),
      child: Column(
        children: [
          TextField(
            decoration: InputDecoration(
              hintText: 'Search...',
              border: OutlineInputBorder(),
              prefixIcon: Icon(Icons.search),
            ),
          ),
          SizedBox(height: 20),
          Expanded(
            child: ListView(
              children: [
                ListTile(
                  leading: Icon(Icons.history),
                  title: Text('Recent Search 1'),
                ),
                ListTile(
                  leading: Icon(Icons.history),
                  title: Text('Recent Search 2'),
                ),
                ListTile(
                  leading: Icon(Icons.history),
                  title: Text('Recent Search 3'),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class ProfileTab extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          CircleAvatar(
            radius: 50,
            backgroundImage: NetworkImage('https://picsum.photos/100/100?random=profile'),
          ),
          SizedBox(height: 20),
          Text('John Doe', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
          SizedBox(height: 10),
          Text('[email protected]'),
          SizedBox(height: 30),
          ElevatedButton(
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(content: Text('Edit profile clicked')),
              );
            },
            child: Text('Edit Profile'),
          ),
        ],
      ),
    );
  }
}

// 7. Custom Widget Example
class CustomWidgetApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Widgets',
      home: CustomWidgetScreen(),
    );
  }
}

class CustomWidgetScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Widgets'),
      ),
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          children: [
            CustomCard(
              title: 'Custom Card',
              description: 'This is a custom widget card',
              icon: Icons.star,
              color: Colors.blue,
            ),
            SizedBox(height: 16),
            CustomCard(
              title: 'Another Card',
              description: 'This card has different content',
              icon: Icons.favorite,
              color: Colors.red,
            ),
            SizedBox(height: 16),
            CustomProgressBar(
              progress: 0.75,
              label: 'Loading Progress',
            ),
          ],
        ),
      ),
    );
  }
}

class CustomCard extends StatelessWidget {
  final String title;
  final String description;
  final IconData icon;
  final Color color;

  const CustomCard({
    required this.title,
    required this.description,
    required this.icon,
    required this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.3),
            spreadRadius: 2,
            blurRadius: 5,
            offset: Offset(0, 3),
          ),
        ],
      ),
      child: Row(
        children: [
          Container(
            padding: EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: color.withOpacity(0.1),
              borderRadius: BorderRadius.circular(8),
            ),
            child: Icon(icon, color: color, size: 30),
          ),
          SizedBox(width: 16),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  title,
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 4),
                Text(
                  description,
                  style: TextStyle(
                    color: Colors.grey[600],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class CustomProgressBar extends StatelessWidget {
  final double progress;
  final String label;

  const CustomProgressBar({
    required this.progress,
    required this.label,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          label,
          style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
        ),
        SizedBox(height: 8),
        Container(
          height: 20,
          decoration: BoxDecoration(
            color: Colors.grey[300],
            borderRadius: BorderRadius.circular(10),
          ),
          child: FractionallySizedBox(
            alignment: Alignment.centerLeft,
            widthFactor: progress.clamp(0.0, 1.0),
            child: Container(
              decoration: BoxDecoration(
                color: Colors.green,
                borderRadius: BorderRadius.circular(10),
              ),
            ),
          ),
        ),
        SizedBox(height: 4),
        Text('${(progress * 100).toInt()}%'),
      ],
    );
  }
}