Aplicacions amb Flutter, Dart i Flame

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

Afegim la consulta de les dones joves

El web també ens ofereix la possibilitat de consultar la llista de dones joves (nascudes de l'any 2000 en endavant), que torna un format igual al de les dones catalanes.

Ara afegirem un segon botó que ens permetrà veure aquesta altra llista. Ens caldrà fer alguns petits canvis en la pantalla principal i en la funció que fa la crida web.

Per a la crida, podem modificar la classe CridaLlistaDones; atès que les dues crides són gairebé idèntiques, només cal modificar un paràmetre a l'adreça URL. Així, doncs, afegirem un paràmetre a la funció demanarLlistaDones.

crida_llista_dones.dart
import 'dart:convert';
import 'package:dones_destacades/data/dades_rebudes_dones.dart';
import 'package:http/http.dart' as http;  // No el troba automàticament, s'ha d'entrar a mà
class CridaLlistaDones{
  Future<DadesRebudesDones?> demanarLlistaDones(String tip) async{
    final llistaDonesRebuda = await 
      http.get(Uri.parse("https://recursos.citcea.upc.edu/dones/service.php?tipus=$tip"));
    if(llistaDonesRebuda.statusCode == 200){
      var jsonDecodificat = jsonDecode(llistaDonesRebuda.body);
      DadesRebudesDones dadesRebudesDones = DadesRebudesDones.fromJson(jsonDecodificat);
      return dadesRebudesDones;
    } else {
      return null;
    }
  }
}

A la pantalla principal hem de fer alguns canvis. Per un costat, caldrà afegir una filera per tal que els dos botons es vegin de costat. El segon botó serà similar al primer però canviarà el text; en els dos, cal afegir el paràmetre que es passa a la crida.

Atès que les dues llistes es mostraran al mateix lloc i de la mateixa forma, sembla oportú afegir un títol que indiqui què s'està veien. S'ha creat la variable titol que es mostra en un text sota els botons i que té un contingut que varia segons quin botó es prem.

pant_principal.dart
import 'package:dones_destacades/data/crida_llista_ambits.dart';
import 'package:dones_destacades/data/crida_llista_dones.dart';
import 'package:dones_destacades/data/dades_dona_llista.dart';
import 'package:dones_destacades/data/dades_rebudes_dones.dart';
import 'package:dones_destacades/screens/pant_detalls.dart';
import 'package:flutter/material.dart';
import 'package:html_unescape/html_unescape.dart';  // No ho posa automàticament
class PantPrincipal extends StatefulWidget {
  const PantPrincipal({super.key});

  @override
  State<PantPrincipal> createState(){
    return _PantPrincipalState();
  }
}

class _PantPrincipalState extends State<PantPrincipal> {
  Map<String, String> _dadesAmbits = {};
  Future<DadesRebudesDones?>? _dadesDones;
  CridaLlistaDones cridaLlistaDones = CridaLlistaDones();
  CridaLlistaAmbits cridaLlistaAmbits = CridaLlistaAmbits();
  bool _carregat = false;
  String titol = "Dones destacades";

  @override
  void initState() {
    super.initState();
    _carregarDades();
  }

  Future<void> _carregarDades() async {
    final dades = await cridaLlistaAmbits.demanarLlistaAmbits();
    setState(() {
      _dadesAmbits = dades;
      _carregat = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Dones destacades"),),
      body: Column(
        children: [
          Row(
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextButton(
                  onPressed: () {
                    setState(() {
                      _dadesDones = cridaLlistaDones.demanarLlistaDones("cat");
                      titol = "Dones catalanes";
                    });
                  },
                  child: Text("Dones catalanes"),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextButton(
                  onPressed: () {
                    setState(() {
                      _dadesDones = cridaLlistaDones.demanarLlistaDones("joves");
                      titol = "Dones joves";
                    });
                  },
                  child: Text("Dones joves"),
                ),
              ),
            ],
          ),
          Container(
            alignment: Alignment.topLeft,
            padding: const EdgeInsets.all(8),
            child: Text(titol, style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold))
          ),
          mostraLlista()
        ],
      ),
    );
  }

  FutureBuilder<DadesRebudesDones?> mostraLlista() {
    return FutureBuilder(future: _dadesDones, builder: (context, snapshot){
      if(snapshot.connectionState == ConnectionState.waiting){
        return CircularProgressIndicator();
      } else if(snapshot.hasError){
        return Text("Error: ${snapshot.error}");
      } else if(snapshot.hasData){
        var llistaDones = snapshot.data?.llistaDadesDonaLlista;
        return Expanded(
          child: ListView.builder(
            itemCount: llistaDones?.length ?? 0,
            itemBuilder: (context, index) {
              if(llistaDones != null){
                return mostraElement(llistaDones[index]);
              } else {
                return Text("Error a la llista");
              }
            },
          ),
        );
      } else {
        return Text("No s'han trobat resultats");
      }
    });
  }

  Padding mostraElement(DadesDonaLlista donaDeLaLlista) {
    var unescape = HtmlUnescape();
    String ambitAct = "";
    if(_carregat){
      ambitAct = _dadesAmbits[donaDeLaLlista.ambit].toString();
    }
    return Padding(
      padding: const EdgeInsets.all(5.0),
      child: GestureDetector(
        onTap: () => Navigator.push(context, MaterialPageRoute(
            builder: (context) => PantDetalls(persona: donaDeLaLlista.id, dadesAmbits: _dadesAmbits, carregat: _carregat),
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(unescape.convert(donaDeLaLlista.nom), 
              style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)),
            Text(unescape.convert(donaDeLaLlista.professio), 
              style: TextStyle(fontSize: 13)),
            if(_carregat && ambitAct.isNotEmpty) 
              Text("Àmbit: ${unescape.convert(ambitAct)}", style: TextStyle(fontSize: 13)),
          ]
        )
      )
    );
  }
}

 

 

 

 

 

 

 

 

 

 

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