Tutorial su Flutter: come sviluppare app con l’SDK di Google
Chi desidera programmare un'app, ha a disposizione numerose opzioni. Tra le soluzioni più amate per la facilità d’uso, troviamo le strutture già assemblate con componenti di app pronte all’uso; anche i framework stanno spopolando sempre più poiché rendono il processo di sviluppo il più semplice possibile per gli utenti. Una delle soluzioni più moderne è il pacchetto di sviluppo software (o SDK) Flutter sviluppato da Google. Il framework open source permette lo sviluppo di app mobili, per iOS e Android, altamente performanti ma anche di applicazioni web e desktop nel linguaggio di Google Dart.
Nel nostro tutorial su Flutter vi presentiamo i passaggi più importanti per utilizzare il pacchetto di sviluppo software di Google.
Conoscere Flutter: le premesse
Per imparare a programmare con Flutter non sono necessarie conoscenze pregresse sullo sviluppo web e di applicazioni. Non bisogna neppure conoscere Dart, il linguaggio di programmazione di Google sopra citato. Se avete già familiarità con codici orientati all’oggetto e concetti basilari di programmazione, come variabili, cicli e condizioni, allora partirete già da una buona base per lavorare con il framework.
In questo tutorial su Flutter vogliamo offrirvi una prima panoramica per lo sviluppo con questo SDK e per farlo scriveremo una semplice app, che combina le parole tra loro secondo un modello casuale presentando queste combinazioni alla fine. Per questo abbiamo bisogno degli strumenti base per programmare con Flutter: il pacchetto SDK Flutter e un editor. Il primo è disponibile per Windows, macOS e Linux; potrete scaricare il relativo pacchetto di installazione direttamente dal sito ufficiale di Flutter.
Per quel che riguarda l'editor, non siete vincolati a una scelta. Per un’esperienza utente ottimale con completamento intelligente del codice automatico, colorazione della sintassi e supporto nel debug e nella modifica di widget, Google consiglia l’utilizzo di un editor di codice e offre anche un plug-in ufficiale di Flutter. Per questo motivo, nel nostro tutorial su Flutter utilizzeremo Android Studio. Dopo aver installato questo ambiente di sviluppo ottimizzato per Android, configurate il plug-in di Flutter come indicato di seguito:
- Aprite la voce del menu “File”.
- Fate clic su “Settings” e selezionate la rubrica “Plugins”.
- Digitate “Dart” nella casella di ricerca e sul risultato che vi apparirà con lo stesso nome fate clic sul tasto “Install” per installare l'estensione necessaria per il linguaggio di programmazione Dart.
- Confermate l’utilizzo dell'estensione di terzi con “Accept”.
- Ripetete lo stesso procedimento per il termine di ricerca “Flutter” e dopo l'installazione avvenuta con successo premete su “Restart IDE” per salvare le modifiche.
Come alternativa ad Android Studio, Google consiglia di utilizzare GNU Emacs, Visual Studio Code e IntelliJ IDEA, tutte applicazioni per cui esiste già un plug-in ufficiale di Flutter.
Passaggio 1: creare la propria app con Flutter
Dopo aver installato Flutter nell'ambiente di sviluppo (o editor) desiderato, potete creare la vostra prima applicazione con Flutter. Come già anticipato, in questo tutorial utilizzeremo Android Studio, motivo per cui avvieremo subito l’ambiente di sviluppo integrato per questo scopo. Attraverso il menu “File” dovete selezionare prima la voce “New” e poi “New Flutter Project” per avviare un nuovo progetto sulla base del framework per app.
Selezionate “Flutter Application” come tipo di progetto desiderato e premete su “Next”. Nel menu di configurazione potete definire il titolo del progetto e la memoria locale per l’applicazione. Potete anche inserire una descrizione facoltativa del progetto. Nella riga “Flutter SDK path” inserite il percorso per il framework installato di Flutter.
Fate clic infine su “Finish” per creare una nuova app Flutter. Nel file main.dart, che corrisponde al file di lavoro di base di un progetto e di questo tutorial su Futter, inserite il codice seguente per presentare l’app con un semplice messaggio “Hello World” (potete eliminare il codice già presente nel file main.dart):
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title:'Welcome to Flutter',
home:Scaffold(
appBar:AppBar(
title:Text('Welcome to Flutter'),
),
body:Center(
child:Text('Hello World'),
),
),
);
}
}
Una volta inserito lo snippet, potete visualizzare la presentazione della prima versione della vostra app. Su Android Studio selezionate allora la macchina virtuale relativa (alla voce “Flutter Device Selection”) e premete infine sul tasto di riproduzione (“Run main.dart”):
Per visualizzare un'anteprima di un'applicazione in Android Studio, è necessario installare un'image di sistema della piattaforma di destinazione desiderata. In caso contrario, alla voce “Flutter Device Selection” non riuscirete a selezionare alcun dispositivo di prova virtuale per testare l'app. Per aggiungerne uno, selezionate le voci di menu “Tools” e “AVD Manager”. Fate clic infine su “Create Virtual Device” e installate il dispositivo virtuale di vostra scelta. Nel forum per sviluppatori di Android troverete una guida dettagliata per creare e amministrare dispositivi virtuali con Android Studio.
Il primo avvio o debugging dell'app potrebbe impiegare un po’ di tempo. Per questo dovrete pazientare un po’ prima di riuscire a visualizzare il messaggio di benvenuto sullo schermo del vostro ambiente di prova.
Passaggio 2: installare un pacchetto esterno
Dopo aver imparato nel primo passaggio del tutorial a creare una prima semplice applicazione, occorre adesso ampliarla con un pacchetto esterno. Per essere più precisi, dovremo installare il pacchetto di parole necessario ai fini del nostro progetto, ove per progetto si intende un’applicazione che combini tra loro delle parole secondo uno schema casuale. Come esempio utilizzeremo il pacchetto open source “english_words” (con licenza MIT) che potrete trovare insieme a tanti altri pacchetti gratuiti sulla piattaforma pub.dev. Il modulo contiene 5000 parole inglesi tra le più comuni e per questo è particolarmente indicato per lo scopo di questo tutorial sul funzionamento di Flutter.
Le applicazioni Flutter utilizzano il file pubspec.yaml per gestire pacchetti e dipendenze. Aprite questo file e inserite nell'elenco delle dipendenze una voce per il pacchetto di lingue (prestare attenzione alla versione corrente; in questo caso: 3.1.5):
dependencies:
flutter:
sdk: flutter
cupertino_icons:^0.1.2
english_words:^3.1.5
Eseguite infine il comando “flutter pub get”. Android Studio ha addirittura un pulsante specifico per questo scopo chiamato “Pub get”.
Ritornate al file di lavoro principale main.dart dove importerete il pacchetto di lingue:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
Inserite nel codice dell’app la riga seguente:
final wordPair = WordPair.random();
Infine sostituite la voce child, responsabile del risultato del testo “Hello World” con la voce qui riportata:
child:Text(wordPair.asPascalCase),
Ogni volta che eseguirete questo codice di app aggiornato, otterrete una coppia di parole inglesi generate casualmente.
Passaggio 3: aggiungere uno stateful widget
Gli stateless widget, come utilizzati finora in questo tutorial su Flutter di Google, sono statici. Ciò significa che, per il tempo di esecuzione di un’app, non potranno essere modificati perché questo tipo di widget non può essere sovrascritto durante l'esecuzione dell'app. Gli stateful widget, invece, possono modificare il loro stato anche durante il tempo di esecuzione dell'app, permettendo di non doverlo già definire al momento dell'esecuzione. Perciò, se volete conferire alla vostra app Flutter precisi elementi interattivi, avete bisogno di stateful widget.
I widget in Flutter sono sempre stateless o stateful. Esempi tipici di componenti stateless sono le icone, i tasti o i testi boilerplate. Esempi comuni di semplici widget stateful sono le checkbox, i formulari o i cursori.
Anche il nostro esempio di app dovrà contenere a questo punto un widget interattivo. Per l’implementazione sono necessarie almeno due classi: una StatefulWidget class, che genera a sua volta un’istanza di state class.
Per cominciare, creiamo una state class minimale chiamata “RandomWordsState”, nella quale inseriremo il codice seguente alla fine del file main.dart:
class RandomWordsState extends State<randomwords> {</randomwords>
// TODO Add build() method
}
In questo caso, la state class generica è stata assegnata esplicitamente all’utilizzo in combinazione con il widget “RandomWords”. Lo stateful widget stesso verrà scritto nel prossimo passaggio con l’input seguente nel file main.dart (nel codice: prima della class “RandomWordsState”):
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => RandomWordsState();
}
Eseguendo questo nuovo codice dell’app, Flutter vi comunicherà che al momento non è ancora definita alcuna funzione build() per il “RandomWordsState”.
Nello snippet inserito della state class, troverete il commento a carattere jolly “//TODO Add build() method” nella posizione designata, che sarà ora sostituito dal codice per la funzione build():
class RandomWordsState extends State<randomwords> {</randomwords>
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
Infine eliminate la riga “final wordPair = WordPair.random();” dalla class MyApp e sostituite la voce child “child:Text(wordPair.asPascalCase),” con “child:RandomWords(),“.
Eseguite adesso questo nuovo codice. Il dispositivo di prova virtuale dovrebbe generare le coppie di parole come in precedenza, ma sulla base di uno stateful widget, che potenzialmente permette anche l’interazione con l’utente.
Passaggio 4: creare un elenco con scroll infinito
Per fornirvi un primo esempio di widget di Flutter interattivo, nell’ultima parte di questo tutorial su Flutter di Google, amplieremo la nostra app ancora un po’: per essere più precisi, la classe “RandomWordsState” dovrà essere personalizzata in modo da non presentare più solo coppie singole di parole, ma una lista infinita di coppie di parole tra cui scorrere. Inoltre, le coppie di parole proposte saranno salvate, per evitare voci doppie, e le dimensioni dei caratteri del risultato saranno ingrandite.
Cominciamo con l’ultimo punto, ovvero il salvataggio dei risultati presentati e la personalizzazione del font. Per ciò, basterà installare un elenco _suggestions e una variabile _biggerFont:
class RandomWordsState extends State<randomwords> {</randomwords>
final _suggestions = <wordpair>[];</wordpair>
final _biggerFont = const TextStyle(fontSize:18.0);
}
Infine inserite nella class “RandomWordsState” la relativa funzione_buildSuggestions():
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder:(context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
La funzione mostrata permette l’estensione dell’app con varie caratteristiche. Tra queste troviamo l’integrazione dell'elenco delle coppie di parole (List.View) che sarà ancora più visibile grazie alla linea divisoria di un pixel (Divider). Inoltre definiremo che saranno forniti altri dieci suggerimenti (riga: _suggestions.addAll) quando l’utente arriverà alla fine dell'elenco presentato.
Un’ulteriore componente base del widget ampliato è costituita dalla funzione _buildRow(), attivata una volta per ogni coppia di parole e che presenta tali coppie come ListTitle. Implementeremo questa funzione nel prossimo passaggio:
Widget _buildRow(WordPair pair) {
return ListTile(
title:Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
Ora bisognerà istruire il metodobuild(), già implementato per lo stateful widget nel passaggio 3, per utilizzare la funzione buildSuggestions(). Il contenuto del metodo utilizzato finora deve essere cambiato con il seguente codice:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Word Generator'),
),
body: _buildSuggestions(),
);
}
Infine dovrete aggiornare il metodo build() anche nella class MyApp, dove modificherete il Title e definirete alla voce Home che si tratta di un widget RandomWords:
title: 'Word Generator',
home: RandomWords(),
Eseguendo nuovamente il codice, l'app funzionerà con il nuovo titleName “Word Generator”. Inoltre sarà presentato un intero elenco di combinazioni di parole nel quale vi basterà scorrere verso il basso per vedere altri risultati.
Tutorial su Flutter: sintesi
Nel corso di questo tutorial avete imparato le basi per lavorare con Flutter e il modo in cui applicarle in una semplice app di esempio. Naturalmente potrete sviluppare le vostre applicazioni personalizzate con Flutter in modo ancora più dettagliato ed esteso. Dopo uno studio un po’ più approfondito del framework potrete personalizzarne anche il design.
Per concludere vi presentiamo ancora una volta il codice completo dell’esempio di app sviluppato per Android nel file main.dart:
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Word Generator',
home: RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => RandomWordsState();
}
class RandomWordsState extends State<randomwords> {</randomwords>
final _suggestions = <wordpair>[];</wordpair>
final _biggerFont = const TextStyle(fontSize:18.0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Word Generator'),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder:(context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair) {
return ListTile(
title:Text(
pair.asPascalCase,
style:_biggerFont,
),
);
}
}