Nella lezione precedente, abbiamo preso familiarità con il framework e compreso le differenze che vi sono tra gli stateless e gli stateful widget e i rispettivi metodi per disegnare il widget ed il suo contenuto.
Flutter mette a disposizione dello sviluppatore diverse tipologie di widget pronte all’utilizzo che ci permetteranno di costruire a nostra volta nuovi widget per comporre l’interfaccia utente della nostra applicazione.
In questa lezione, analizzeremo e faremo alcuni esempi di utilizzo di uno dei principali Widget
offerti da Flutter, il widget Container
.
Container
Il widget Container
è tra i più utilizzati durante la realizzazione dell’interfaccia utente di un’app, in quanto combina tra loro diverse tipologie di widget riguardanti la posizione e le dimensioni. Come stesso il nome lascia intendere, questo widget funge da contenitore per un widget figlio gestendone le dimensioni, il background e molto altro ancora.
Le proprietà
Come tutti i widget che abbiamo visto nel corso di queste lezioni, il widget Container
fornisce un insieme di proprietà che, se definite, ne modificano il comportamento nella caratterizzazione del proprio layout. Tra queste ritroviamo:
Proprietà | Tipo Accettato | Descrizione |
---|---|---|
alignment
|
AlignmentGeometry
|
allinea il widget figlio in relazione al Container
AlignmentGeometry
Alignment
AlignmentDirectional
|
child
|
Widget
|
è la proprietà da utilizzare per associare all’istanza del Container
|
constraints
|
BoxConstraints
|
definisce ulteriori vincoli da applicare al widget figlio. Per fare ciò va definito un oggetto di tipo BoxConstraints
|
decoration
|
Decoration
|
attraverso questa proprietà è possibile definire una descrizione di come deve essere disegnato il Container
Decoration
BoxDecoration
ShapeDecoration
|
margin
|
EdgeInsetsGeometry
|
questa proprietà permette di definire uno spazio attorno alla decoration
EdgeInsets
EdgeInsetsDirectional
EdgeInsetsGeometry
|
padding
|
EdgeInsetsGeometry
|
diversamente dalla proprietà margin
padding
padding
EdgeInsets
EdgeInsetsDirectional
|
transform
|
Matrix4
|
questa proprietà offre la possibilità di definire una matrice di trasformazione da applicare al Container
Container
Matrix4
Container
|
Comportamento nella definizione del layout
Come si è potuto evincere dalla rapida panoramica delle proprietà offerte, il widget Container
combina un insieme di widget diversi, ognuno dei quali è caratterizzato da un un proprio comportamento per il layout. Ciò rende la gestione del layout del Container
più articolata. In generale, il Container
cercherà di eseguire in ordine le seguenti operazioni:
- rispettare l’allineamento imposto;
- modificare le proprie dimensioni al fine di adattarsi a quelle del proprio widget figlio;
- rispettare l’altezza, la larghezza ed i vincoli indicati;
- espandersi per adattarsi al nodo padre;
- essere il più piccolo possibile.
Entrando più nello specifico, possiamo distinguere diversi casi, riassunti nella seguente tabella.
Caso | Descrizione |
---|---|
il Container
|
il Container
|
il Container
|
il Container
|
il Container
alignment
|
il Container
|
il Container
alignment
|
il Container
|
il Container
|
il Container
alignment
|
il Container
constraints
alignment
|
il Container
|
Esempi pratici
Vediamo adesso alcuni esempi pratici per creare diverse tipologie di Container
utilizzando le proprietà offerte da questo widget.
Per iniziare, creiamo un nuovo progetto o partiamo dal progetto di esempio creato nella lezione 7 e modifichiamo il file main.dart all’interno del package lib come segue.
Lasciando intatti l’import
iniziale e il metodo main
, modifichiamo la classe MyApp
.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lesson 11 - Container Widget',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: null,
);
}
}
Come possiamo notare, abbiamo costruito un nuovo StatelessWidget
composto dalle proprietà title
, theme
, e home
. Quest’ultima verrà inizializzata con un nuovo widget, al cui interno riporteremo i nostri esempi.
Creiamo quindi la classe ContainerExample
come uno semplice StatelessWidget
che conterrà una lista di diversi esempi di Container
che possiamo costruire.
Iniziamo quindi con la creazione di questa classe e di un semplice Container
avente come figlio un widget Text
.
class ContainerExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Lesson 11 - Container Widget'),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
color: Colors.orange,
child: Text("Basic Container"),
)
],
)));
}
}
Analizzando il codice scritto possiamo notare che abbiamo creato un nuovo widget Scaffold
che definisce un appBar
e un body
composto dal widget SingleChildScrollView
, estremamente utile quando abbiamo un unico elemento che potrebbe non essere interamente visibile nello schermo del dispositivo. In questo esempio, abbiamo definito come figlio un widget Column
che mostra i suoi figli in un array verticale ed ha come widget figlio una lista di Container
. In questo caso, abbiamo inserito nel nostro array di Widget
solo un Container
di cui abbiamo definito le proprietà color
e child
.
È importante comprendere che, sebbene sia una soluzione per mostrare tanti elementi in una lista, questa non è la soluzione più efficiente per mostrare tanti widget. A tal proposito si consiglia di utilizzare una ListView
che vedremo più avanti nel corso di questa guida.
Eseguiamo quindi l’applicazione, ottenendo il seguente risultato.
Aggiungiamo ora, attraverso le proprietà width
height
Container
children: <Widget>[
//. . .
Container(
width: 300.0,
height: 50.0,
color: Colors.teal,
child: Text("Container width = 300 , height = 50"),
),
]
Eseguendo l’applicazione avremo il seguente risultato in cui è presente anche il precedente Container
Figura 58. Visualizzazione del Container con le dimensioni impostate e del precedente Container per a) Android e b) iOS (click per ingrandire)
Contrariamente, se volessimo aggiungere le proprietà margin
padding
Container
EdgeInsets
only()
children: <Widget>[
// . . .
Container(
color: Colors.yellow,
margin:
EdgeInsets.only(left: 10.0, right: 50.0, top: 10, bottom: 30),
padding:
EdgeInsets.only(left: 25.0, right: 25.0, top: 10, bottom: 10),
child: Container(
color: Colors.orangeAccent[200],
child: Text("Container with margin and padding"),
),
),
]
Effettuiamo l’Hot Reload dell’app ottenendo il seguente risultato.
Figura 59. Visualizzazione del Container con le proprietà padding e margin definite e dei precedenti Container per a) Android e b) iOS (click per ingrandire)
Come si può notare, abbiamo aggiunto dello spazio intorno al Container
padding
Creiamo adesso un Container
alignment
AlignmentGeometry
Alignment
height
Container
children: <Widget>[
// . . .
Container(
color: Colors.lightBlue,
alignment: Alignment.bottomRight,
height: 200,
child: Text("Container with child alignment"),
),
]
Eseguiamo quindi l’Hot Reload per visualizzare la modifica effettuata.
Figura 60. Visualizzazione del Containter con allineamento in basso a sinistra del widget figlio e dei precedenti Container per a) Android e b) iOS (click per ingrandire)
Complichiamo leggermente lo scenario e definiamo un Container che definisca le proprietà:
constraint
BoxConstaint
padding
all()
EdgeInsets
decoration
ShapeDecoration
In particolare, immaginiamo di dover creare un box con i bordi arrotondati. Per farlo dovremo definire la proprietà shape di ShapeDecoration
creando l’oggetto RoundedRectangleBorder
come segue.
children: <Widget>[
// . . .
Container(
constraints: BoxConstraints.expand(height: 100.0, width: 200),
padding: EdgeInsets.all(10),
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
),
color: Colors.red),
child: Text("Container with ShapeDecoration"),
),
]
Tramite l’Hot Reload potremo vedere la modifica effettuata.
Figura 61. Visualizzazione del Container dai bordi arrotondati e dei precedenti Container per a) Android e b) iOS (click per ingrandire)
Chiudiamo infine i nostri esempi definendo una trasformata. In particolare vogliamo ruotare sull’asse delle ascisse il nostro Container
rotationY
Matrix4
children: <Widget>[
// . . .
Container(
padding: EdgeInsets.only(top: 10, left: 10),
constraints: BoxConstraints.expand(width: 200, height: 150),
color: Colors.lightGreenAccent[700],
transform: Matrix4.rotationY(pi / 5)..rotateX(pi / 5),
child: Text("this.transform"),
)
]
Eseguiamo nuovamente l’app ottenendo il seguente risultato.
Figura 62. Visualizzazione del Container ruotato e dei precedenti Container per a) Android e b) iOS (click per ingrandire)
Il codice di questa lezione è disponibile al seguente link