Chi desidera pro­gram­ma­re un'app, ha a di­spo­si­zio­ne numerose opzioni. Tra le soluzioni più amate per la facilità d’uso, troviamo le strutture già as­sem­bla­te con com­po­nen­ti di app pronte all’uso; anche i framework stanno spo­po­lan­do 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 svi­lup­pa­to da Google. Il framework open source permette lo sviluppo di app mobili, per iOS e Android, altamente per­for­man­ti ma anche di ap­pli­ca­zio­ni web e desktop nel lin­guag­gio di Google Dart.

Nel nostro tutorial su Flutter vi pre­sen­tia­mo i passaggi più im­por­tan­ti per uti­liz­za­re il pacchetto di sviluppo software di Google.

Conoscere Flutter: le premesse

Per imparare a pro­gram­ma­re con Flutter non sono ne­ces­sa­rie co­no­scen­ze pregresse sullo sviluppo web e di ap­pli­ca­zio­ni. Non bisogna neppure conoscere Dart, il lin­guag­gio di pro­gram­ma­zio­ne di Google sopra citato. Se avete già fa­mi­lia­ri­tà con codici orientati all’oggetto e concetti basilari di pro­gram­ma­zio­ne, come variabili, cicli e con­di­zio­ni, allora partirete già da una buona base per lavorare con il framework.

In questo tutorial su Flutter vogliamo offrirvi una prima pa­no­ra­mi­ca per lo sviluppo con questo SDK e per farlo scri­ve­re­mo una semplice app, che combina le parole tra loro secondo un modello casuale pre­sen­tan­do queste com­bi­na­zio­ni alla fine. Per questo abbiamo bisogno degli strumenti base per pro­gram­ma­re con Flutter: il pacchetto SDK Flutter e un editor. Il primo è di­spo­ni­bi­le per Windows, macOS e Linux; potrete scaricare il relativo pacchetto di in­stal­la­zio­ne di­ret­ta­men­te dal sito ufficiale di Flutter.

Per quel che riguarda l'editor, non siete vincolati a una scelta. Per un’espe­rien­za utente ottimale con com­ple­ta­men­to in­tel­li­gen­te del codice au­to­ma­ti­co, co­lo­ra­zio­ne 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 uti­liz­ze­re­mo Android Studio. Dopo aver in­stal­la­to questo ambiente di sviluppo ot­ti­miz­za­to per Android, con­fi­gu­ra­te il plug-in di Flutter come indicato di seguito:

  1. Aprite la voce del menu “File”.
  2. Fate clic su “Settings” e se­le­zio­na­te la rubrica “Plugins”.
  3. Digitate “Dart” nella casella di ricerca e sul risultato che vi apparirà con lo stesso nome fate clic sul tasto “Install” per in­stal­la­re l'e­sten­sio­ne ne­ces­sa­ria per il lin­guag­gio di pro­gram­ma­zio­ne Dart.
  4. Con­fer­ma­te l’utilizzo del­l'e­sten­sio­ne di terzi con “Accept”.
  5. Ripetete lo stesso pro­ce­di­men­to per il termine di ricerca “Flutter” e dopo l'in­stal­la­zio­ne avvenuta con successo premete su “Restart IDE” per salvare le modifiche.
N.B.

Come al­ter­na­ti­va ad Android Studio, Google consiglia di uti­liz­za­re GNU Emacs, Visual Studio Code e IntelliJ IDEA, tutte ap­pli­ca­zio­ni per cui esiste già un plug-in ufficiale di Flutter.

Passaggio 1: creare la propria app con Flutter

Dopo aver in­stal­la­to Flutter nel­l'am­bien­te di sviluppo (o editor) de­si­de­ra­to, potete creare la vostra prima ap­pli­ca­zio­ne con Flutter. Come già an­ti­ci­pa­to, in questo tutorial uti­liz­ze­re­mo Android Studio, motivo per cui avvieremo subito l’ambiente di sviluppo integrato per questo scopo. At­tra­ver­so il menu “File” dovete se­le­zio­na­re prima la voce “New” e poi “New Flutter Project” per avviare un nuovo progetto sulla base del framework per app.

Se­le­zio­na­te “Flutter Ap­pli­ca­tion” come tipo di progetto de­si­de­ra­to e premete su “Next”. Nel menu di con­fi­gu­ra­zio­ne potete definire il titolo del progetto e la memoria locale per l’ap­pli­ca­zio­ne. Potete anche inserire una de­scri­zio­ne fa­col­ta­ti­va del progetto. Nella riga “Flutter SDK path” inserite il percorso per il framework in­stal­la­to di Flutter.

Fate clic infine su “Finish” per creare una nuova app Flutter. Nel file main.dart, che cor­ri­spon­de al file di lavoro di base di un progetto e di questo tutorial su Futter, inserite il codice seguente per pre­sen­ta­re 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 vi­sua­liz­za­re la pre­sen­ta­zio­ne della prima versione della vostra app. Su Android Studio se­le­zio­na­te allora la macchina virtuale relativa (alla voce “Flutter Device Selection”) e premete infine sul tasto di ri­pro­du­zio­ne (“Run main.dart”):

N.B.

Per vi­sua­liz­za­re un'an­te­pri­ma di un'ap­pli­ca­zio­ne in Android Studio, è ne­ces­sa­rio in­stal­la­re un'image di sistema della piat­ta­for­ma di de­sti­na­zio­ne de­si­de­ra­ta. In caso contrario, alla voce “Flutter Device Selection” non riu­sci­re­te a se­le­zio­na­re alcun di­spo­si­ti­vo di prova virtuale per testare l'app. Per ag­giun­ger­ne uno, se­le­zio­na­te le voci di menu “Tools” e “AVD Manager”. Fate clic infine su “Create Virtual Device” e in­stal­la­te il di­spo­si­ti­vo virtuale di vostra scelta. Nel forum per svi­lup­pa­to­ri di Android troverete una guida det­ta­glia­ta per creare e am­mi­ni­stra­re di­spo­si­ti­vi virtuali con Android Studio.

Il primo avvio o debugging dell'app potrebbe impiegare un po’ di tempo. Per questo dovrete pa­zien­ta­re un po’ prima di riuscire a vi­sua­liz­za­re il messaggio di benvenuto sullo schermo del vostro ambiente di prova.

Passaggio 2: in­stal­la­re un pacchetto esterno

Dopo aver imparato nel primo passaggio del tutorial a creare una prima semplice ap­pli­ca­zio­ne, occorre adesso ampliarla con un pacchetto esterno. Per essere più precisi, dovremo in­stal­la­re il pacchetto di parole ne­ces­sa­rio ai fini del nostro progetto, ove per progetto si intende un’ap­pli­ca­zio­ne che combini tra loro delle parole secondo uno schema casuale. Come esempio uti­liz­ze­re­mo il pacchetto open source “english_words” (con licenza MIT) che potrete trovare insieme a tanti altri pacchetti gratuiti sulla piat­ta­for­ma pub.dev. Il modulo contiene 5000 parole inglesi tra le più comuni e per questo è par­ti­co­lar­men­te indicato per lo scopo di questo tutorial sul fun­zio­na­men­to di Flutter.

Le ap­pli­ca­zio­ni Flutter uti­liz­za­no il file pubspec.yaml per gestire pacchetti e di­pen­den­ze. Aprite questo file e inserite nel­l'e­len­co delle di­pen­den­ze una voce per il pacchetto di lingue (prestare at­ten­zio­ne 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 ad­di­rit­tu­ra un pulsante specifico per questo scopo chiamato “Pub get”.

Ritornate al file di lavoro prin­ci­pa­le main.dart dove im­por­te­re­te 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 so­sti­tui­te la voce child, re­spon­sa­bi­le del risultato del testo “Hello World” con la voce qui riportata:

child:Text(wordPair.asPascalCase),

Ogni volta che ese­gui­re­te questo codice di app ag­gior­na­to, otterrete una coppia di parole inglesi generate ca­sual­men­te.

Passaggio 3: ag­giun­ge­re uno stateful widget

Gli stateless widget, come uti­liz­za­ti finora in questo tutorial su Flutter di Google, sono statici. Ciò significa che, per il tempo di ese­cu­zio­ne di un’app, non potranno essere mo­di­fi­ca­ti perché questo tipo di widget non può essere so­vra­scrit­to durante l'e­se­cu­zio­ne dell'app. Gli stateful widget, invece, possono mo­di­fi­ca­re il loro stato anche durante il tempo di ese­cu­zio­ne dell'app, per­met­ten­do di non doverlo già definire al momento del­l'e­se­cu­zio­ne. Perciò, se volete conferire alla vostra app Flutter precisi elementi in­te­rat­ti­vi, avete bisogno di stateful widget.

N.B.

I widget in Flutter sono sempre stateless o stateful. Esempi tipici di com­po­nen­ti stateless sono le icone, i tasti o i testi boi­ler­pla­te. 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 in­te­rat­ti­vo. Per l’im­ple­men­ta­zio­ne sono ne­ces­sa­rie almeno due classi: una Sta­te­ful­Wid­get class, che genera a sua volta un’istanza di state class.

Per co­min­cia­re, creiamo una state class minimale chiamata “Ran­dom­Words­Sta­te”, nella quale in­se­ri­re­mo 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 espli­ci­ta­men­te all’utilizzo in com­bi­na­zio­ne con il widget “Ran­dom­Words”. Lo stateful widget stesso verrà scritto nel prossimo passaggio con l’input seguente nel file main.dart (nel codice: prima della class “Ran­dom­Words­Sta­te”):

class RandomWords extends StatefulWidget {
	@override
	RandomWordsState createState() => RandomWordsState();
}

Eseguendo questo nuovo codice dell’app, Flutter vi co­mu­ni­che­rà che al momento non è ancora definita alcuna funzione build() per il “Ran­dom­Words­Sta­te”.

Nello snippet inserito della state class, troverete il commento a carattere jolly “//TODO Add build() method” nella posizione designata, che sarà ora so­sti­tui­to 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 so­sti­tui­te la voce child “child:Text(wordPair.asPa­scal­Ca­se),” con “child:Ran­dom­Words(),“.

Eseguite adesso questo nuovo codice. Il di­spo­si­ti­vo di prova virtuale dovrebbe generare le coppie di parole come in pre­ce­den­za, ma sulla base di uno stateful widget, che po­ten­zial­men­te permette anche l’in­te­ra­zio­ne con l’utente.

Passaggio 4: creare un elenco con scroll infinito

Per fornirvi un primo esempio di widget di Flutter in­te­rat­ti­vo, nell’ultima parte di questo tutorial su Flutter di Google, am­plie­re­mo la nostra app ancora un po’: per essere più precisi, la classe “Ran­dom­Words­Sta­te” dovrà essere per­so­na­liz­za­ta in modo da non pre­sen­ta­re 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 di­men­sio­ni dei caratteri del risultato saranno in­gran­di­te.

Co­min­cia­mo con l’ultimo punto, ovvero il sal­va­tag­gio dei risultati pre­sen­ta­ti e la per­so­na­liz­za­zio­ne del font. Per ciò, basterà in­stal­la­re un elenco _sug­ge­stions e una variabile _big­ger­Font:

class RandomWordsState extends State<randomwords> {</randomwords>
	final _suggestions = <wordpair>[];</wordpair>
	final _biggerFont = const TextStyle(fontSize:18.0);
}

Infine inserite nella class “Ran­dom­Words­Sta­te” la relativa funzione_build­Sug­ge­stions():

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’esten­sio­ne dell’app con varie ca­rat­te­ri­sti­che. Tra queste troviamo l’in­te­gra­zio­ne dell'elenco delle coppie di parole (List.View) che sarà ancora più visibile grazie alla linea divisoria di un pixel (Divider). Inoltre de­fi­ni­re­mo che saranno forniti altri dieci sug­ge­ri­men­ti (riga: _sug­ge­stions.addAll) quando l’utente arriverà alla fine del­l'e­len­co pre­sen­ta­to.

Un’ulteriore com­po­nen­te base del widget ampliato è co­sti­tui­ta dalla funzione _buildRow(), attivata una volta per ogni coppia di parole e che presenta tali coppie come ListTitle. Im­ple­men­te­re­mo questa funzione nel prossimo passaggio:

Widget _buildRow(WordPair pair) {
	return ListTile(
		title:Text(
			pair.asPascalCase,
			style: _biggerFont,
		),
	);
}

Ora bisognerà istruire il me­to­do­build(), già im­ple­men­ta­to per lo stateful widget nel passaggio 3, per uti­liz­za­re la funzione build­Sug­ge­stions(). Il contenuto del metodo uti­liz­za­to 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 ag­gior­na­re il metodo build() anche nella class MyApp, dove mo­di­fi­che­re­te il Title e de­fi­ni­re­te alla voce Home che si tratta di un widget Ran­dom­Words:

title: 'Word Generator',
home: RandomWords(),

Eseguendo nuo­va­men­te il codice, l'app fun­zio­ne­rà con il nuovo titleName “Word Generator”. Inoltre sarà pre­sen­ta­to un intero elenco di com­bi­na­zio­ni 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 ap­pli­car­le in una semplice app di esempio. Na­tu­ral­men­te potrete svi­lup­pa­re le vostre ap­pli­ca­zio­ni per­so­na­liz­za­te con Flutter in modo ancora più det­ta­glia­to ed esteso. Dopo uno studio un po’ più ap­pro­fon­di­to del framework potrete per­so­na­liz­zar­ne anche il design.

Per con­clu­de­re vi pre­sen­tia­mo ancora una volta il codice completo dell’esempio di app svi­lup­pa­to 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,
			),
		);
	}
}
Vai al menu prin­ci­pa­le