Hello Flutter!

La struttura di un progetto Flutter

Cliccando sul pulsante in alto a destra, si può accedere al repository contenente il codice hello Flutter esaminato in questa lezione. La cartella contiene diversi file e sottocartelle, vediamo quelli più interessanti.

  • Il file pubspec.yaml specifica tutti i parametri del progetto tra cui: nome, versione sdk, dipendenza pacchetti, …
  • La directory lib contiene il codice dart e flutter, in questa directory lavoreremo nella maggior parte di casi
  • La directory android contiene file specifici per la versione Android della App, in questa directory (precisamente nella sottodirectory app/src/main) si trova il file AndroidManifest.xml che va modificato per garantire i corretti permessi.

Come è ormai consuetudine, iniziamo l’esplorazione di Flutter con il classico Hello World!. Questa app può essere creata seguendo il codelab Write your first Flutter app.

In questa lezione capiremo:

  1. la struttura base di una applicazione Flutter;
  2. il concetto di StatelessWidget.

Punto di partenza: il main

Nel main di ogni applicazione flutter tutto ciò che va fatto è invocare la funzione runApp passando come parametro un’istanza di una classe appropriata. Nel nostro esempio, la classe è MyApp che estende StatelessWidget.

import 'package:flutter/material.dart';

void main() {
    runApp(MyApp());
}

Notiamo anche l’import del package flutter/material.dart che verrà utilizzato per dare un aspetto material design alla App. Lo stesso import, renderà disponibile la funzione runApp utilizzata nel main.

Root Widget

Ogni applicazione Flutter è composta da widget, in effetti tutto in Flutter è un widget (bottoni, testo, gesture, …). Il widget principale (chiamato root widget) è quello che viene passato alla funzione runApp nel main.

Nel nostro esempio il root widget è ottenuto come istanza della classe MyApp che estende StatelessWidget. Il costruttore senza nome utilizzato nell’esempio si limita ad inizializzare la variabile d’istanza key della classe StatelessWidget con il valore passato (o il default se nessun valore viene passato come nel main sopra).

class MyApp extends StatelessWidget {
    const MyApp({super.key});
    // ...
}

Il metodo build

Ogni widget ha un metodo build che restituisce un oggetto di tipo Widget che rappresenta la struttura da visualizzare. Nel root widget MyApp del nostro esempio, di questo metodo viene fatto l’override.

Widget build(BuildContext context) {
    // ...
}

Il parametro context (della classe BuildContext) viene utilizzato dal widget per capire il suo rapporto con altri widget, cioè il suo contesto (Video esplicativo (in inglese)).

Il metodo build è quindi responsabile della “costruzione” del widget, infatti nel nostro esempio questo metodo restituisce un oggetto di tipo MaterialApp, in altre parole l’intera app è una material app.

Widget build(BuildContext context) {
    return MaterialApp(
            // ...
        );
}

La classe MaterialApp ha un costruttore con decine di parametri nominali (vedi API qui), nel nostro esempio ne usiamo solo due:

  • title (String) che rappresenta il titolo della nostra app, non visibile sullo schermo,
  • home (Widget) che rappresenta il contenuto (ancora un Widget!) della app, cioè tutto ciò che è visibile sullo schermo.
class MyApp extends StatelessWidget {
    const MyApp({super.key});

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Welcome to Flutter',
            home:  // ...
        );
    }
}

Infine, la parte visibile dello schermo viene creata utilizzando un oggetto Scaffold che contiene un barra superiore (AppBar) ed un testo centrato (Text all’interno di un Center)

class MyApp extends StatelessWidget {
    const MyApp({super.key});

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Hello Flutter',
            home: Scaffold(
                appBar: AppBar(
                    title: const Text('Welcome to Flutter'),
                ),
                body: const Center(
                    child: Text('Hello World'),
                ),
            ),
        );
    }
}
Osserva

Come detto sopra tutto in Flutter è un Widget, andando a vedere la documentazione ufficiale, infatti, si vedrà come tutte le seguenti classi derivano (direttamente o indirettamente) da Widget: MaterialApp, Scaffold, AppBar, Center e Text.

È interessante notare come alcuni di questi widget siano utilizzati per il layout (ad esempio Scaffold e Center) ed altri siano utilizzati per disegnare elementi dell’interfaccia (ad esempio AppBar e Text).

Vedremo nelle prossime lezioni che anche gli oggetti per riconoscere le gesture (ad esempio lo scuotimento del dispositivo), sono in realtà dei Widget.

Importante

Il widget MaterialApp viene utilizzato specialmente nelle applicazioni Android, esiste anche il widget CupertinoApp più specifico per le applicazioni iOS. È ovviamente possibile utilizzare i due widget in modo che quando viene creato la app Android si usi l’uno e quando viene creata quelle iOS si usi l’altro. Questo corso, tuttavia, non è sufficientemente avanzato da poter affrontare questa tematica che può essere studiata nella documentazione online di Flutter.

  • Michele Schimd © 2024
  • Ultimo aggiornamento: 17/02/2024
  • Materiale di studio e di esercizio per gli alunni dello Zuccante.

Creative Commons License