Programmare applicazioni mobili con flutter

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
Ora è sorto un nuovo problema, mentre stavo lavorando su android studio, si è chiuso il progetto facendomi perdere le ultime modifiche non salvate.

Riaprendo il progetto, e provandolo, ricevo questo errore in console:
Codice:
Launching lib/main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...

FAILURE: Build failed with an exception.

* Where:
Build file '/home/mic/progetti-applicazioni/appprovo/android/app/build.gradle' line: 24

* What went wrong:
A problem occurred evaluating project ':app'.
> Failed to apply plugin [class 'org.gradle.api.plugins.BasePlugin']
   > Could not create service of type OutputFilesRepository using ExecutionGradleServices.createOutputFilesRepository().

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 417ms
Exception: Gradle task assembleDebug failed with exit code 1
E' successo di punto in bianco, senza aver fatto niente.

Provando ad aprire i vecchi progetti seguiti dai codelab, tutto funziona bene. E' solo questa app, che tenevo aperta. Qualche file si può essere danneggiato? Tengo presente che la cartella dei progetti è montata da condivisione samba in lan.

Grazie
 

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
Ho dovuto reinstallare android studio e flutter per riparare il problema, ora funziona tutto bene.

Mi sono dilettato a riguardo di ChangeNotifier e dintorni, e per ora non ho avuto problemi. Devo dire ottima trovata da parte dei creatori del dart mettendo queste funzionalità. :ok:

Ora ho un piccolo intoppo riguardante la tipizzazione di una variabile. Il json avuto dalla sorgente http è questo:
JSON:
[
        {
            "catnid": 101,
            "nome": "Bar/Ristoranti/Pizzerie",
            "icona": "MdiIcons.food-fork-drink",
            "coloreicona": 4291444800
        },
        {
            "catnid": 110,
            "nome": "Supermercati",
            "icona": "Icons.shopping_cart",
            "coloreicona": 4280439256
        },
        {
            "catnid": 205,
            "nome": "Farmacie",
            "icona": "Icons.add",
            "coloreicona": 4281103636
        }
    ]
E il tipizzatore è questo:
JavaScript:
class TipizzataCategoria {
  @required
  final int numero;
  @required
  final String nome;
  final IconData icona;
  final Color coloreicona;
  TipizzataCategoria({
    this.numero,
    this.nome,
    this.icona,
    this.coloreicona,
  });
  factory TipizzataCategoria.dajson(Map<String, dynamic> json) =>
      TipizzataCategoria(
        numero: json['catnid'] as int,
        nome: json['nome'] as String,

        // proviamo così:
        icona: (Icons.json['icona'].toString().toLowerCase() != null ? 'Icons.${json['icona'].toString().toLowerCase()}' : '') as IconData,
        // o così:
        icona: json['icona'] as IconData,

        coloreicona: Color(json['coloreicona'] as int),
      );
}
Mi dà errore che non riesce a convertire una stringa in formato IconData, riguardante il parametro icona. Come vedi le icone non provengono solo dall'oggetto Icons di material, ma anche dal pacchetto material_design_icons_flutter.

Come posso risolvere?

Grazie
 

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
E io proprio questo voglio sapere, avendo dal json una stringa tipo "Icons.add", come faccio a farlo diventare Icons.add?

Non c'è un modo?

Grazie
 

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
Icons.add è di tipo IconData.

Nel mio server è memorizzato il valore "Icons.add" in un campo di mysql. Quando viene consegnato all'app in formato json, viene così:
JSON:
"icona": "Icons.add",
Ma poi, nell'app voglio inanzitutto controllare se esiste un oggetto IconData con valore Icons.add, se c'è metto quello, altrimenti do io un'icona predefinita.
Se in dart questa cosa è impossibile, sono disposto a modificare il lato server (php/mysql), ma non so come.

Consigli?
 

pabloski

Utente Èlite
2,868
916
Eh no. Icons.add è una stringa di testo, non è un oggetto di tipo IconData. Come sei arrivato a quella conclusione?

Non c'è modo di serializzare un oggetto tramite JSON, che è un formato testuale. Ma poi perchè l'oggetto IconData dovrebbe essere memorizzato in un database?

Poi perchè scrivi "memorizzato in un campo di mysql"? Non stai usando un file JSON?
 

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
Mi spiego meglio.

Tramite ChangeNotifier e correlati, ho creato alcune schermate vuote (tutte tab in pagina iniziale) solo con l'oggetto CircularProgressIndicator.
Al momento che viene fatta richiesta al server dell'app, dove ci sono php e mysql, il server preleva dal database e restituisce una lista di contenuti in formato json da inserire nelle pagine, tra cui i colori con cui riempire gli sfondi degli oggetti e l'icona da mettere negli oggetti.
Per quanto riguarda i colori, non ho problemi, ma sull'icona sì.

Non riesco a trovare un modo per dire al dart di mettere l'icona che gli viene dettata dal server.
Per il colore, invece, nella query sql di inserimento scrivo il numero in forma esadecimale (es: 0xFF2C7514) e lo memorizzo in un campo mysql int unsigned diventando un numero in base decimale (4281103636), quindi nel json in uscita dal server ho questo:
JSON:
"coloreicona": 4281103636
E poi in dart scrivendo Color(4281103636) mi dà il colore esatto che ho specificato io.

Ma per l'icona non riesco a trovare uno stratagemma come quello usato per i colori. Mi basterebbe anche qualcosa tipo eval di php, ma in dart.

Hai qualche idea su come fare?

EDIT: ho trovato qualcosa riguardante purtroppo solo Icons di material, dove ogni icona specificata nella lista, specifica come farla, es. IconData(58746, fontFamily: 'MaterialIcons')
Quindi io posso memorizzare nel db il numero intero e il nome font. Ma questo riguarda solo le icone material, ma io ho aggiunto anche questo pacchetto al mio progetto app e non so come fare ora.
 
Ultima modifica:

pabloski

Utente Èlite
2,868
916
Ho capito. Ma devi decidere se le icone stanno sul server o sul client.

Se stanno sul server, devi memorizzarle o nel database direttamente ( tramite un oggetto blob ) oppure memorizzi il nome del file dell'icona, poi leggi questo file e ne spedisci il contenuto al client.

Come hai fatto tu, il client riceve un nome. E i byte che compongono l'icona, cioè la bitmap, dove stanno?

JavaScript:
IconData(58746, fontFamily: 'MaterialIcons')

Questo qui è ancora un'altra cosa. Perchè specifica quale icona andare a pescare da un font che contiene solo icone. Ma il file che contiene queste icone, va aggiunto come risorsa all'applicazione e quindi verrà inserito nel pacchetto dell'app.

Dopo di che, basta effettivamente solo quel primo numero, per indicare quale icona prendere.
 

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
Non ho ben capito il tuo consiglio.

Allora io le icone le ho nel client, sono icone predefinite di material (es. Icons.add) e icone prelevate dal pacchetto flutter_icons (es. FontAwesome.newspaper_o). Il vero e proprio file dell'icona (la bitmap) risiede nell'app, non nel server.

Il server deve comunicare al client QUALE icona visualizzare all'utente, così come viene fatto con i colori, dove l'oggetto Color() risiede nel client e il server gli comunica QUALE colore usare.

Non so ora come fare.
 

pabloski

Utente Èlite
2,868
916
Se vai in font_awesome_flutter.dart, troverai scritta una cosa come questa

JavaScript:
class FontAwesomeIcons {
  static const IconData fiveHundredPx = const IconDataBrands(0xf26e);
  static const IconData accessibleIcon = const IconDataBrands(0xf368);
  static const IconData accusoft = const IconDataBrands(0xf369);
  static const IconData acquisitionsIncorporated = const IconDataBrands(0xf6af);
  static const IconData ad = const IconDataSolid(0xf641);
  static const IconData addressBook = const IconDataRegular(0xf2b9);
  static const IconData solidAddressBook = const IconDataSolid(0xf2b9);
  static const IconData addressCard = const IconDataRegular(0xf2bb);
  static const IconData solidAddressCard = const IconDataSolid(0xf2bb);
  static const IconData adjust = const IconDataSolid(0xf042);

Quindi quel FontAwesomeIcons.newspaper_o non è un altro che un oggetto della classe IconData.

Che è fatta così https://api.flutter.dev/flutter/widgets/IconData-class.html

Quegli IconDataBrands, IconDataRegular, IconDataSolid, sono delle classi factory che servono per costruire un oggetto di tipo IconData.


Il vantaggio di queste ultime è che basta passargli un numero per indicare quale icona si vuole.

Quindi nel database o ci metti un numero + il tipo di classe factory che andrai ad usare per ricostruire IconData. Oppure serializzi IconData, mettendo nel database i parametri che servono per creare un oggetto di classe IconData.

Chiaro che, in quest'ultimo caso, devi fare la produce che farebbero IconDataSolid, IconDataRegular, IconDataBrands, ecc... Cioè, da qualche parte, chiameranno il costruttore di IconData, passandogli dei parametri e tu dovrai passare gli stessi parametri.

In soldoni devi salvare nel database le proprietà degli oggetti di questa classe https://api.flutter.dev/flutter/widgets/IconData-class.html
 

hddsfortuna

Utente Attivo
869
39
Net
FTTH 1000/300
OS
Ubuntu 22.04
In soldoni devi salvare nel database le proprietà degli oggetti di questa classe https://api.flutter.dev/flutter/widgets/IconData-class.html
Questo l'ho capito dall'inizio, e ora direi che stiamo nella strada giusta per arrivare al traguardo. :ok:

Dato che le icone che devo inserire nel database non sono tante (più o meno 50), posso vedere per ogni icona i parametri da inserire. Dalla documentazione sono questi:
JavaScript:
IconData(int codePoint, {String fontFamily, String fontPackage, bool matchTextDirection: false})

Quindi, per l'oggetto IconData, il json proveniente dal server sarà così:
JSON:
"icona-numero-intero": 200,
"icona-font-nome": 'nome font',
"icona-font-pacchetto": 'nome pacchetto',
E poi così:
JSON:
IconData quale_icona = IconData(codePoint: json['icona-numero-intero'], fontFamily: json['icona-font-nome'], fontPackage: json['icona-font-pacchetto']);
Inoltre vorrei controllare (se possibile) se l'icona in oggetto effettivamente esiste o no. Può essere che nel db possono trovarsi dati sbagliati. Non sono solo io ad inserire le icone.

Ora però devo trovare i parametri delle icone. Ho aperto il pacchetto flutter_icons, e all'icona che mi serve vedo questo:
JSON:
class FontAwesome {
// altre icone
static const IconData newspaper_o = const FlutterIconData.fontAwesome(61930);
}
Ma ora non so come recuperare i 3 parametri da inserire nel db.

Come posso fare?

Grazie
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!