Aplicacions amb Flutter, Dart i Flame

Tutorial Flutter Flame Projectes   Recursos CITCEA
Exemples Dart Dades pràctiques     Inici

Mètodes (funcions)

Els mètodes ens permeten separar trossos de programa que fan una funció específica. Són molt útils per a aquelles accions que es repeteixen en diverses parts del programa. En la definició d'un mètode cal indicar quins són els seus paràmetres (variables que li passem com a dades d'entrada, no sempre necessàries) i de quin tipus és la seva sortida (si és que retorna alguna cosa, no sempre és així). La definició d'un mètode ha d'estar sempre fora del main; que, de fet, és un mètode més però que actúa com a mètode principal. Per exemple:

void inicialitzar(){
  ...
}

crea una funció anomenada inicialitzar que no té cap paràmetre i no retorna res (per això hi diu void). Per cridar (executar) la funció, l'haurem d'invocar des del programa principal (main).

void main(){
  inicialitzar();
  ...
}

Els mètodes poden tenir un o més paràmetres i en la definició cal indicar de quin tipus seran. En el moment de cridar a la funció podem donar els paràmetres emprant una variable o posant un valor.

void main(){
  int p = 5;
  inicialitzar(p, 47.2);
  ...
}
void calcul(int a, double m){
  ...
}

Els mètodes poden retornar un valor, en quin cas cal indicar de quin tipus serà.

void main(){
  double p = calc();
  ...
}
double calc(){
  double a = 23.5;
  double b = 11.3;
  ...
  double produc = a * b;
  return produc;
}

Les variables declarades dins d'un mètode són locals i, per tant, deixen d'existir quan s'està fora del mètode. Dos o més mètodes (inclòs el main) poden tenir, doncs, variables amb el mateix nom.

Evidentment, un mètode pot tenir paràmetres i retornar resultats.

void main(){
  double m = 23.5;
  double p = calc(m, 11.3);
  ...
}
double calc(double a, double b){
  ...
  double produc = a * b;
  return produc;
}

El mètode anterior es pot simplificar, prescindint de la variable produc.

double calc(double a, double b){
  ...
  return a * b;
}

Tampoc és imprescindible guardar la resposta en una variable, es pot utilitzar directament.

void main(){
  double m = 23.5;
  print("La resposta és ${calc(m, 11.3)}");
  ...
}

Mètodes amb paràmetres opcionals

Existeix la possibilitat de definir com a opcionals els paràmetres d'un mètode; en quin cas, caldrà definir un valor per defecte. Per exemple:

double calc({double a = 0.0, double b = 1.0}){
  ...
}

fixem-nos que els paràmetres ara estan entre claus (a més del parèntesi).

Atès que els paràmetres són opcionals; si els posem, cal indicar a quin paràmetre correspon cada valor.

void main(){
  double p = calc(b: 11.3);
  ...
}

Un mètode pot tenir alguns paràmetres necessàries i altres opcionals. En aquest cas, els opcionals es posen entre claudàtors.

void funcio(int a, [int b = 0, int c = 1]){
  int m = a + b - c;
  print(m);
}

En aquest cas, els paràmetres b i c són opcionals. Podem indicar-los els dos:

...
  funcio(4, 3, 2);
...

o només un, en quin cas serà el primer (b = 3):

...
  funcio(4, 3);
...

o no indicar-ne cap:

...
  funcio(4);
...

Les funcions senzilles es poden escriure en un format simplificat, per exemple:

int perim(int p, int q) => 2 * (p + q);

que és el mateix que:

int perim(int p, int q){
  return 2 * (p + q);
}

Mètodes i variables definits en un giny superior

Quan una variable està definida en un giny o un mètode no és accessible des dels altres ginys i mètodes que estan al seu mateix nivell o en nivells superiors. És molt habitual, però que un giny tingui algun element (un botó, per exemple) que modifiqui una variable que ens fa falta en un altre lloc, com podria ser un altre giny. Per aconseguir-ho, cal definir aquestes variables en el nivell més alt comú, per exemple a la pantalla principal. De la mateixa manera, els mètodes que modifiquen aquestes variables també han d'estar en aquest nivell superior comú.

En aquest exemple ens cal tenir una variable que anomenenm tensAlim que s'ha de modificar des del giny SelectorTens però ha d'estar disponible per a altres ginys que formen part, com ell, de la pantalla principal.

Com ja hem dit, hem anomenat tensAlim a la variable global que tindrà sempre el valor corresponent a la tensió d'alimentació. El selector de tensió tindrà un paràmetre tensioAlim al qual li passarem aquest valor, ja que el necessitem dins el giny. Quan l'usuari premi un dels botons del selector, s'executarà la funció canviTens que està definida a la pantalla principal. Aquesta funció retorna el valor novaTensio que passarà a substituir el que hi havia a tensAlim.

En la pantalla principal, hem posat aquestes línies:

...
class _PantPralState extends State<PantPral> {
  double tensAlim = 3.3; // V
  ...
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SelectorTens(
          tensioAlim: tensAlim,
          canviTens: (double novaTensio) {
            setState(() {
              tensAlim = novaTensio;
            });
          },
        ),
        ...
      ],
    );
  }
}

En el giny SelectorTens hi hem posat aquestes línies:

class SelectorTens extends StatefulWidget {
  final double tensioAlim;
  final Function(double novaTens) canviTens;
  const SelectorTens({super.key, required this.tensioAlim, required this.canviTens});

  @override
  State<SelectorTens> createState() => _SelectorTensState();
}

class _SelectorTensState extends State<SelectorTens> {
  double tensio = 3.3;
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: GestureDetector(
            onTap: () {
              setState(() {
                widget.canviTens(3.3);
              });
            },
            child: Padding(
              padding: const EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 10),
              child: Container(
                alignment: Alignment.center,
                decoration: BoxDecoration(
                  color: widget.tensioAlim == 3.3 ? ColorsApp.compSelec : ColorsApp.component,
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: Text("3,3 V", style: Estils.estilTextBotons),
                ),
              ),
            ),
          ),
        ),
        Expanded(
          child: GestureDetector(
            onTap: () {
              setState(() {
                widget.canviTens(5.0);
              });
            },
            child: Padding(
              padding: const EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 20),
              child: Container(
                alignment: Alignment.center,
                decoration: BoxDecoration(
                  color: widget.tensioAlim == 5.0 ? ColorsApp.compSelec : ColorsApp.component,
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: Text("5,0 V", style: Estils.estilTextBotons),
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

 

 

 

 

 

 

 

 

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.