---
# System prepended metadata

title: Flutter. Gestió d'estats (01. Provider)
tags: [daw, ' programacio']

---


<div style="width: 30%; margin-left: auto;">
    
![](https://hackmd.io/_uploads/HJiR4eGJT.png)    
    
</div>

<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Llicència de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Aquesta obra està subjecta a una llicència de <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Reconeixement-CompartirIgual 4.0 Internacional de Creative Commons</a>

# Flutter. Gestió d'estats (01. Provider)
Flutter és un framework que utilitza el paradigma de la [programació declarativa de la UI](https://docs.flutter.dev/data-and-backend/state-mgmt/declarative), que en poques paraules ve a significar que redibuixa tota la interface gràfica a cada canvi d'estat; els canvis d'estat provoquen un rebuild total dels widgets.
Hem vist que podem comunicar dades i events entre diferents widgets enviant paràmetres i callbacks pels contructors dels diferents descendents, però aquest mètode pot arribar a ser una tasca feixuga i difícil de mantenir.
Flutter ofereix una extensa [llista amb diferents aproximacions de com abordar el tema de la gestió dels estats](https://docs.flutter.dev/data-and-backend/state-mgmt/options), en aquesta ocasió ens centrarem a comprendre la classe [__Provider__](https://pub.dev/packages/provider), que com tot a Flutter, és un _widget_. 

> Us deixo un enllaç sobre el tema a una xerrada durant la *Google i/o 2019*: [**Pragmatic State Management in Flutter**](https://youtu.be/d_m5csmrf7I?feature=shared).

## El paquet **Provider**
Per començar a utilitzar el paquet Provider a la nostra app, el primer que necessitem fer és declarar-lo al fitxer __pubspec.yaml__, una forma pramàtica de fer-ho és utilitzar la comanda:
```=
$ flutter pub add provider
Resolving dependencies... 
  collection 1.17.2 (1.18.0 available)
  flutter_lints 2.0.3 (3.0.0 available)
  lints 2.1.1 (3.0.0 available)
  material_color_utilities 0.5.0 (0.8.0 available)
  meta 1.9.1 (1.11.0 available)
+ nested 1.0.0
+ provider 6.0.5
  stack_trace 1.11.0 (1.11.1 available)
  stream_channel 2.1.1 (2.1.2 available)
  test_api 0.6.0 (0.6.1 available)
  web 0.1.4-beta (0.3.0 available)
Changed 2 dependencies!
```

I ja el podem importar al nostre fitxers main.dart:

    import 'package:provider/provider.dart';

Ara ja estem llestos per a utilitzar les classes que ens ofereix el paquet Provider. La primera cosa que farem serà crear el model de l'estat de la nostra aplicació; crearem una nova classe que hereti de ChangeNotifier. En realitat no és estrictament necessari utilitzar ChangeNotifier amb Provider, però ens farà la vida una mica més fácil:

```dart=
import "package:flutter/material.dart";

class LlistaArticles extends ChangeNotifier {
  final List<Article> _articles = [];

  void afegeix(Article article) {
    _articles.add(article);
    notifyListeners();
  }

  void treu(Article article) {
    _articles.remove(article);
    notifyListeners();
  }

  Article itemAt(int index) {
    return _articles[index];
  }

  Article getByNom(String nom) {
    return _articles.firstWhere((article) => article.nom == nom);
  }

  int count() {
    return _articles.length;
  }
}

class Article {
  int? id;
  String nom = "";
  int? quantity = 0;

  Article({
    required this.id,
    required this.nom,
    required this.quantity,
  });
}
```
A la classe anterior hem incorporat també alguns mètodes que proporcionen utilitats que no modifiquen l'estat i consegüentment no han d'informar als Listeners. Encara falten els mètodes necessaris per incrementar i decrementar les quantitats de cada element.

El Widget proporcionat per Flutter que subministra un ChangeNotifier als seus descendents es diu [**ChangeNotifierProvider**](https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider-class.html) i si fem que el nostre node arrel sigui un node d'aquest tipus, tota la nostra app tindrà accés al model que acabem de crear.

A partir d'ara la nostra funció principal quedarà així:
```dart=
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => LlistaArticles(),
      child: MyApp(),
    ),
  );
}
```

Arribats a aquest punt, ja no te sentit utilitzar Stateful Widgets a la nostra app, ja que la informació d'estat queda restringida a la classe LlistaArticles que hereta de ChangeNotifier.
