El paquet provider és una solució popular per a la gestió de l'estat en aplicacions Flutter. És fàcil d'utilitzar, escalable i es basa en els principis de la programació reactiva. En aquest tema, aprendrem com utilitzar el paquet provider per gestionar l'estat de la nostra aplicació.

Continguts

Introducció al Paquet Provider

El paquet provider és una implementació de la Inversió de Dependències (DI) i la Injecció de Dependències (DI) per a Flutter. Permet compartir dades entre diferents parts de l'aplicació de manera eficient i reactiva.

Avantatges del Paquet Provider

  • Simplicitat: És fàcil d'entendre i implementar.
  • Escalabilitat: Pot gestionar estats simples i complexos.
  • Reactivitat: Actualitza automàticament els widgets quan les dades canvien.

Instal·lació del Paquet Provider

Per començar a utilitzar el paquet provider, primer hem d'afegir-lo al nostre projecte Flutter.

  1. Obre el fitxer pubspec.yaml.
  2. Afegeix la dependència del provider:
dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0
  1. Executa flutter pub get per instal·lar el paquet.

Creació d'un Model de Dades

Abans de poder utilitzar el provider, necessitem un model de dades. Crearem una classe simple que representi el nostre model.

class CounterModel with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

Explicació del Codi

  • CounterModel: És la nostra classe de model que conté l'estat.
  • ChangeNotifier: És una classe de Flutter que proporciona la funcionalitat de notificació de canvis.
  • _count: És una variable privada que emmagatzema el valor del comptador.
  • increment: És un mètode que incrementa el valor del comptador i notifica els oients dels canvis.

Proveïdor de Dades

Ara que tenim el nostre model de dades, necessitem proporcionar-lo a la nostra aplicació. Utilitzarem el widget ChangeNotifierProvider per fer-ho.

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CounterModel(),
      child: MyApp(),
    ),
  );
}

Explicació del Codi

  • ChangeNotifierProvider: Proporciona una instància de CounterModel a l'arbre de widgets.
  • create: És una funció que crea una nova instància de CounterModel.
  • MyApp: És el widget principal de la nostra aplicació.

Consum de Dades

Per consumir les dades proporcionades pel provider, utilitzarem el widget Consumer.

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Provider Example'),
      ),
      body: Center(
        child: Consumer<CounterModel>(
          builder: (context, counter, child) {
            return Text(
              'Count: ${counter.count}',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<CounterModel>(context, listen: false).increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

Explicació del Codi

  • Consumer<CounterModel>: Consumeix les dades del CounterModel.
  • builder: És una funció que es crida cada vegada que les dades canvien.
  • Provider.of<CounterModel>(context, listen: false): Obté una instància de CounterModel sense escoltar els canvis.

Exemple Pràctic

A continuació, es mostra un exemple complet que combina tots els passos anteriors.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CounterModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Provider Example'),
      ),
      body: Center(
        child: Consumer<CounterModel>(
          builder: (context, counter, child) {
            return Text(
              'Count: ${counter.count}',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<CounterModel>(context, listen: false).increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class CounterModel with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

Exercicis Pràctics

  1. Exercici 1: Crea una aplicació que utilitzi el provider per gestionar una llista de tasques. Implementa funcionalitats per afegir i eliminar tasques.
  2. Exercici 2: Modifica l'exemple pràctic per afegir un botó que decrementi el valor del comptador.

Solucions

Solució Exercici 1:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => TaskModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TaskPage(),
    );
  }
}

class TaskPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Task Manager'),
      ),
      body: Column(
        children: [
          Expanded(
            child: Consumer<TaskModel>(
              builder: (context, taskModel, child) {
                return ListView.builder(
                  itemCount: taskModel.tasks.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(taskModel.tasks[index]),
                      trailing: IconButton(
                        icon: Icon(Icons.delete),
                        onPressed: () {
                          taskModel.removeTask(index);
                        },
                      ),
                    );
                  },
                );
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              onSubmitted: (value) {
                Provider.of<TaskModel>(context, listen: false).addTask(value);
              },
              decoration: InputDecoration(
                labelText: 'Add Task',
                border: OutlineInputBorder(),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class TaskModel with ChangeNotifier {
  List<String> _tasks = [];

  List<String> get tasks => _tasks;

  void addTask(String task) {
    _tasks.add(task);
    notifyListeners();
  }

  void removeTask(int index) {
    _tasks.removeAt(index);
    notifyListeners();
  }
}

Solució Exercici 2:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CounterModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Provider Example'),
      ),
      body: Center(
        child: Consumer<CounterModel>(
          builder: (context, counter, child) {
            return Text(
              'Count: ${counter.count}',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () {
              Provider.of<CounterModel>(context, listen: false).increment();
            },
            child: Icon(Icons.add),
          ),
          SizedBox(height: 10),
          FloatingActionButton(
            onPressed: () {
              Provider.of<CounterModel>(context, listen: false).decrement();
            },
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

class CounterModel with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void decrement() {
    _count--;
    notifyListeners();
  }
}

Conclusió

En aquest tema, hem après com utilitzar el paquet provider per gestionar l'estat en aplicacions Flutter. Hem vist com instal·lar el paquet, crear un model de dades, proporcionar-lo a l'aplicació i consumir-lo en els widgets. També hem treballat amb exemples pràctics i exercicis per reforçar els conceptes apresos. Amb aquesta base, estàs preparat per gestionar estats més complexos en les teves aplicacions Flutter.

Curs de Desenvolupament Flutter

Mòdul 1: Introducció a Flutter

Mòdul 2: Conceptes Bàsics de Programació en Dart

Mòdul 3: Widgets de Flutter

Mòdul 4: Gestió de l'Estat

Mòdul 5: Navegació i Enrutament

Mòdul 6: Xarxes i APIs

Mòdul 7: Persistència i Emmagatzematge

Mòdul 8: Conceptes Avançats de Flutter

Mòdul 9: Proves i Depuració

Mòdul 10: Desplegament i Manteniment

Mòdul 11: Flutter per a Web i Escriptori

© Copyright 2024. Tots els drets reservats