App base code - prima App con Flutter

Questa è la prima applicazione che la documentazione ufficiale Flutter porta a realizzare. Corrisponde allo “Step 0: Create the app base code” di quest’altro tutorial. Stessa app, su codelab: https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1#0

Nome del progetto => baseappb

Step 1: Create the starter Flutter app

In Android Studio, cliccare sul menu File -> New -> New Flutter Project e impostare un nome per l’app. Aprire il file /lib/main.dart dell’app appena creata e sostituire il contenuto con il codice seguente:

// 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: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}

Material visual design

Flutter offre molti widget di tipo Material ed è bene avere uses-material-design: true perchè questo permette di utilizzare più risorse del linguaggio Material come ad esempio il pacchetto di icone. Quindi, nel file pubspec.yaml, verificare che sia già presente uses-material-design: true (se non c’è va inserito).

Nel caso in cui si vogliano approfondire le motivazioni di questa prima parte, leggere il capitolo Observations dalla documentazione ufficiale.


Step 2: Use an external package

Dopo aver inserito english_words nel file pubspec.yaml nella sezione dependencies (inserire il codice di seguito)

english_words: ^4.0.0

bisogna rilanciare l’aggiornamento delle dipendenze del progetto:

flutter pub get

Nel main.dart deve essere importato il pacchetto english_words; quindi, subito dopo il pacchetto material.dart va inserita la seguente riga nella sezione alta del file main.dart.

import 'package:english_words/english_words.dart';

La documentazione ci aiuta a creare una coppia di parole casuali e a stamparle al posto di “Hello World” e cioè la scritta impostata nel build() (rivedere codice all’inizio di questo articolo).

Inseriamo quindi tre righe di codice:

  1. una va inserita subito dopo la dichiarazione (e quindi come prima riga) del Widget build() e serve a creare, grazie alla libreria appena importata, una parola casuale da inserire nella variabile wordPair. Di seguito la prima riga da inserire:
final wordPair = WordPair.random();

Le altre due righe si occupano invece di inserire nel body la variabile wordPair e quindi di stamparne a video il contenuto.

body: Center(
  child: Text(wordPair.asPascalCase),

Le due righe precedenti vanno quindi inserite al posto delle seguenti che sono intorno alla riga 20 se i passi precedenti sono stati seguiti correttamente.

body: const Center(
  child: Text('Hello World'),

Rilanciando l’app è possibile vedere che il contenuto della variabile wordPair viene mostrato nel body dell’app. Ma come è chiaro dall’utilizzo, le parole cambiano solo quando l’app viene riavviata, mentre è molto più utile che le parole cambino senza dover riavviare l’app, magari dopo aver premuto un bottone. Per fare questo, cioè per poter modificare il contenuto in questione (quindi il contenuto nel widget, dato che quasi tutto in Flutter è un widget) dovremo utilizzare uno Stateless widget e inserirlo nello Stateless (MyApp) che abbiamo al momento (il primo codice in alto in questo articolo estende infatti StatelessWidget e di conseguenza viene creato come un widget che non può cambiare stato). Lo Stateful widget che andiamo a creare nel prossimo capitolo è invece in grado di cambiare il proprio stato dinamicamente. Vediamo meglio nel prossimo step come funziona questo meccanismo.


Step 3: Add a Stateful widget

Uno stateful widget serve a creare funzionalità dinamiche che cambiano durante l’esecuzione dell’app, mentre uno stateless widget è immutabile, statico, stampato nel layout e non più modificato.

Uno stateful widget è composto da almeno due classi:

1) una classe StatefulWidget che crea l’istanza di una classe State. Questa parte è immutabile e può essere buttata e rigenerata.

2) una class State che a differenza della precedente, esiste per tutto il tempo che dura l’app.

Adesso andiamo a creare uno Stateful widget che la documentazione ufficiale Flutter – step 3 chiama RandomWords che crea la propria classe State chiamandola _RandomWordsState e che poi useremo come child nell’app esistente (MyApp) che rimane Stateless.

  1. creiamo il codice per lo stateful widget portando il cursore in fondo al codice main.dart. Se utilizziamo un IDE come Android Studio, possiamo scrivere stful e l’editor ci chiederà di creare per noi uno Stateful widget completo.
  2. inseriamo il nome RandomWords per il nuovo widget

Automaticamente, se il nome del widget è RandomWords, l’IDE creerà la classe State rinominandola in _RandomWordsState e facendo estendere State<RandomWords> per indicare che stiamo utilizzando una generica classe State che però è stata specializzata per usare RandomWords; la maggior parte della logica dell’applicazione risiede proprio in questa parte che mantiene lo stato per il widget RandomWords e salva la lista delle parole generate che può quindi crescere all’infinito mentre l’utente scrolla le parole (lo scroll genera nuove parole automaticamente per mostrarne sempre di nuove).

Adesso entrambe le classi dovrebbero essere molto simili a queste:

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

class _RandomWordsState extends State<RandomWords> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

3) Aggiorniamo il metodo build() del _RandomWordsState in questo modo:

class _RandomWordsState extends State<RandomWords> {
    @override
    Widget build(BuildContext context) {
      final wordPair = WordPair.random();
      return Text(wordPair.asPascalCase);
    }
}

4) A questo punto abbiamo lo Stateful widget che può cambiare stato dinamicamente; in questo caso, cambierà stato per mostrare nuove parole mentre l’utente le scrolla, non abbiamo più quindi la necessità di riavviare l’app per vedere nuove parole. Nei passi precedenti avevamo inserito nel body la parola generata utilizzando wordPair ma adesso possiamo chiamare direttamente il widget RandomWords() che in questo caso si occuperà di restituire parole casuali, quindi sostituiamo la seguente riga presente nel build() di MyApp

child: Text(wordPair.asPascalCase),

con la seguente:

child: RandomWords(),

Riavviando l’app, verifichiamo che dovrebbe ancora comportarsi allo stesso modo, anche se adesso c’è uno Stateful widget a restituire la parola random, e questo ci permetterà di cambiare il comportamento dell’app nella prossima sezione.


Step 4: Create an infinite scrolling ListView

Questa sezione del tutorial nella documentazione ufficiale di Flutter spiega come espandere _RandomWordsState per generare e mostrare una lista di parole utilizzando una ListView per permettere all’utente di scrollare e vedere le parole oltre lo schermo che vengono anche create dinamicamente come conseguenza dell’azione di scroll.

Estende _RandomWordsState per generare e mostrare una lista di parole casuali; scrollando in basso la lista, la generazione delle parole casuali continua all’infinito.

1) Aggiungiamo la lista _suggestions al _RandomWordsState per salvare le parole suggerite e poi aggiungiamo la variabile _biggerFont per rendere il font più grande. Aggiungiamo quindi le seguenti due righe subito dopo la dichiarazione, come prime righe di _RandomWordsState che estende State<RandomWords>.

final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);

Ora aggiungiamo la funzione _buildSuggestions() alla classe _RandomWordsState() che creerà la ListView che a sua volta mostra le parole suggerite.

2) Aggiungiamo il seguente codice alla _RandomWordsState:

Widget _buildSuggestions() {
  return ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: /*1*/ (context, i) {
        if (i.isOdd) return const Divider(); /*2*/

        final index = i ~/ 2; /*3*/
        if (index >= _suggestions.length) {
          _suggestions.addAll(generateWordPairs().take(10)); /*4*/
        }
        return _buildRow(_suggestions[index]);
      });
}

3) Aggiungiamo la funzione _buildRow() alla _RandomWordsState:

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

4) Nella classe _RandomWordsState() aggiorniamo il metodo build() per usare _buildSuggestions() invece che chiamare direttamente la libreria per generare le parole. Sostituiamo il metodo build() con il seguente codice:

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('Startup Name Generator'),
    ),
    body: _buildSuggestions(),
  );
}

5) Nella classe MyApp aggiorniamo il metodo build() cambiando il titolo e puntando la home al widget RandomWords. Quindi eliminiamo queste righe da MaterialApp:

       title: 'Welcome to Flutter',
       home: Scaffold(
         appBar: AppBar(
           title: const Text('Welcome to Flutter'),
         ),
         body: Center(
           child: RandomWords(),
         ),
       ),

e inseriamo queste due

       title: 'Startup Name Generator',
       home: RandomWords(),

Questa primissima app è completa e la lista può scrollare all’infinito.


Nella documentazione è presente una parte due che aggiunge l’icona dei preferiti ad ogni riga.


Questo sito web non offre alcun cookie perchè non ho interesse a tracciare le attività di nessun utente attraverso i cookie e quindi non ne ho inseriti.
Il tema e i plugin sono realizzati da me e quindi nessun altro è autorizzato ad inserire cookie su questo sito web.
Se qualcuno dovesse individuare un cookie da qualche parte su questo sito web, non ce l'ho messo io,
ed è pregato di farmelo sapere, così potrò cercare e distruggere il cookie eventualmente individuato.
I software e i pezzi di codice condivisi su questo sito web sono da considerarsi a scopo educativo e senza alcuna garanzia
© 2021