Un altro widget immancabile all’interno di una qualsiasi app è il RaisedButton
widget. Attraverso l’utilizzo dei pulsanti, infatti, permettiamo all’utente di compiere un’azione sul nostro dispositivo passando dalla semplice navigazione tra le schermate all’esecuzione di operazioni come il salvataggio di un dato o, più semplicemente, il mostrare un messaggio all’interno di una finestra di dialogo.
In questa lezione focalizzeremo quindi l’attenzione sul RaisedButton
, comprendendone l’utilizzo attraverso semplici ma efficaci esempi.
Il RaisedButton widget
Il RaisedButton
widget rappresenta a tutti gli effetti un pulsante sopra-elevato sulla base delle linee guida dettate dal Material Design.
Questa è solo una delle tante tipologie di pulsanti che possono essere definite all’interno di una app basata su Flutter. Altri esempi, alcuni dei quali saranno oggetto delle prossime lezioni, sono:
Widget | Descrizione |
---|---|
FlatButton |
Pulsante che non definisce alcuna elevazione rispetto al background sottostante e non definisce un’ombra |
FloatingActionButton |
Pulsante circolare con un’icona, posto sempre in primo piano. Definisce un’azione primaria per l’utente. Un semplice esempio di questo pulsante è presente nella lezione 6 |
IconButton |
Pulsante fondamentale quando si vogliono aggiungere azioni nelle AppBar o nelle card |
PopupMenuButton |
Pulsante utile per la definizione di menu a comparsa, che hanno un comportamento simile agli IconButton quando viene fornita un’icona |
Nonostante le diverse tipologie di pulsanti presenti in Flutter, i RaisedButton
sono tra i più utilizzati all’interno di un’app ed è pertanto fondamentale conoscerne le proprietà per sfruttarne al meglio le potenzialità.
Le proprietà
Come tutti i widget, anche, il RaisedButton
fornisce un insieme di proprietà che, se definite, ne modificano il comportamento, caratterizzandone il layout. Tra queste ritroviamo:
Proprietà | Tipo Accettato | Descrizione |
---|---|---|
animationDuration |
Duration |
Definisce un oggetto Duration che specifica la durata delle animazioni per le proprietà shape ed elevation |
child |
Widget |
Permette di specificare il widget figlio del RaisedButton . Generalmente, viene utilizzato un Text widget il cui testo è tutto maiuscolo, ma nulla vieta di impostarlo ad un altro tipo di widget come un’immagine o un icona |
color |
Color |
Definisce il colore di riempimento del pulsante quando è nel suo stato di default, ossia abilitato e non premuto (unpressed ) |
colorBrightness |
Brightness |
Definisce un oggetto Brightness da utilizzare per il pulsante |
disableColor |
Color |
Rappresenta il colore di riempimento quando il pulsante è disabilitato |
disableElevation |
double |
Permette di definire il valore di elevazione rispetto al nodo padre quando il pulsante non è abilitato |
disabledTextColor |
Color |
Definisce il colore da utilizzare per il testo del bottone quando il bottone è disabilitato |
elevation |
double |
È il valore che definisce l’elevazione del pulsante rispetto al nodo padre su un asse z |
enabled |
bool |
Rappresenta quando il bottone è abilitato o meno. Di default i pulsanti sono sempre disabilitati e si abilitano quando la proprietà onPressed è settata |
height |
double |
Altezza del pulsante |
highlightColor |
Color |
Colore dell’highlight dell’InkWell , ossia dell’area rettangolare a cui corrisponde il tocco |
highlightElevation |
double |
Definisce l’elevazione del pulsante rispetto al suo genitore quando il pulsante è abilitato e premuto |
onHighlightChanged |
ValueChanged<bool> |
Viene invocato dall’InkWell relativo al pulsante e definisce una callback che segnala che un valore sottostante è cambiato. In questo caso il valore che cambia è un valore booleano che indica se l’InkWell è stato toccato dall’utente |
onPressed |
VoidCallback |
Permette di definire la callback che viene invocata quando il pulsante viene cliccato o attivato |
minWidth |
double |
Dimensione minima del bottone |
padding |
EdgeInsetsGeometry |
Dimensione dello spazio interno |
shape |
ShapeBorder |
Permette di definire un oggetto ShapeBorder che caratterizza la forma del pulsante in base alle proprie esigenze. Un esempio è un bottone rettangolare con i bordi stondati |
splashColor |
Color |
Il colore da usare per lo splash dell’InkWell |
textColor |
Color |
Definisce il colore da usare per il testo del bottone |
textTheme |
ButtonTextTheme |
Definisce attraverso l'utilizzo del tema i colori di base del pulsante e i valori predefiniti per le dimensioni minime del pulsante, il riempimento interno e la forma. |
Vediamo come utilizzare queste proprietà con alcuni esempi pratici.
Esempi Pratici
Per iniziare, creiamo un nuovo progetto come mostrato in una lezione precedente di questa guida e, lasciando inalterati gli import, il metodo main()
e la classe MyApp
, cancelliamo il resto per aggiungere il seguente StatelessWidget
, composto da uno Scaffold
per la definizione dell’AppBar
e di una SingleChildScrollView
(di cui abbiamo già parlato in una lezione precedente), che conterrà alcuni esempi pratici di utilizzo del widget RaisedButton
.
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Lesson 15 - RaisedButton'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
//we will add our widgets here.
],
)),
);
}
}
Modifichiamo infine la classe MyApp
per impostare il widget appena creato come home.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// . . .
home: MyPage(),
);
}
}
Ora siamo pronti per le nostre sperimentazioni.
Iniziamo da un semplice esempio di creazione del RaisedButton
widget in cui riportiamo semplicemente il testo Click me.
RaisedButton(
onPressed: () {
print("Button clicked"); // print in console
},
child: Text(
"Click Me",
style: TextStyle(color: Colors.teal, fontSize: 30),
)
Eseguendo l’applicazione otterremo il seguente risultato.
Figura 84. Visualizzazione del pulsante Click me per a) Android b) iOS
In particolare, quando premiamo il pulsante verrà stampato in console il messaggio “Button clicked”, definito grazie all’utilizzo della proprietà onPressed
e della relativa callback
come mostrato di seguito.
Figura 85. Output della console contenente il messaggio Button clicked stampato a seguito del click sul pulsante
Come anticipato all’inizio di questa lezione, il child
di questo widget non deve essere necessariamente un Text
widget. Possiamo infatti utilizzare anche altre tipologie di widget, come l’Icon
widget, che ci permettono di definire un’icona rappresentativa per quel bottone. Ad esempio:
RaisedButton(
onPressed: () {
print("click");
},
color: Colors.red,
child: Icon(Icons.add),
)
Analogamente, eseguendo l’applicazione potremo vedere il nostro pulsante rosso con un’icona rappresentante un più e quindi l’azione di un’aggiunta.
Figura 86. Visualizzazione di un RaisedButton con un’icona al posto del testo per a) Android b) iOS
Vediamo adesso come definire un bottone con le seguenti caratteristiche:
- sfondo viola;
- testo in bianco;
highlight
dell’InkWell
rosso;splash
dell’InkWell
tendente al nero.
Per farlo vanno definite le diverse proprietà color relative a questi attributi. Vediamo come attraverso un semplice esempio.
RaisedButton(
onPressed: () {
print("Button clicked");
},
child: Text(
"Button with colored text, highlight and splash",
style: TextStyle(fontSize: 25),
),
color: Colors.purple,
textColor: Colors.white,
highlightColor: Colors.red,
splashColor: Colors.black26
)
Eseguiamo l’applicazione per vedere il risultato.
Figura 87a. Visualizzazione di un pulsante con i colori di sfondo, testo, highlight e splash impostati per Android
Figura 87b. Visualizzazione di un pulsante con i colori di sfondo, testo, highlight e splash impostati per iOS
Come si può notare, di default il colore del pulsante è viola, il testo è in bianco, e quando viene premuto è possibile vedere lo splash
dell’InkWell
in nero, mentre il bottone diventa rosso per indicare che è stato schiacciato dall’utente.
Oltre alla proprietà onPressed
, un’altra proprietà che permette di definire una callback
è onHighlightChanged
, che permette l’esecuzione di un’operazione quando l’utente clicca sul bottone e quest’ultimo viene evidenziato dallo splash dell’InkWell
. Vediamo un esempio di seguito.
RaisedButton(
onPressed: () {
print("Button clicked");
},
onHighlightChanged: (isHigh) {
print("onHighlightChanged.isHigh = $isHigh");
},
child: Text(
"Button with onHightlightChanged",
style: TextStyle(color: Colors.teal, fontSize: 35),
),
)
Figura 88. Visualizzazione del pulsante con la proprietà onHightlightChanged
per a) Android e b) iOS
In questo caso, eseguendo l’app, possiamo vedere che il bottone è simile a quelli visti in precedenza con la differenza che verranno eseguite due operazioni:
- quella definita da
onPressed
, che stamperà il messaggio “Button clicked”; - quella definita da
onHightlightChanged
, che stamperà il messaggio “onHighlightChanged.isHigh = true” (o false) quando viene cliccato il pulsante e l’evento di highlight del bottone viene scatenato.
Entrambe in questo caso stamperanno un messaggio nella console come si può notare di seguito.
Figura 89. Output della console quando viene cliccato il pulsante
Spesso è necessario disabilitare un pulsante finché l’utente non compie una specifica operazione per abilitarlo. Come ad esempio leggere le policy o compilare una form. Per farlo impostiamo la proprietà onPressed
a null
e impostiamo il colore per il testo e per lo sfondo del pulsante quando è disabilitato. In questo modo esso risulterà esteticamente diverso all’utente rispetto ad un bottone abilitato, come quelli visti in precedenza, e non potrà compiere operazioni. Di seguito riportiamo un semplice esempio.
RaisedButton(
onPressed: null,
child: Text(
"Disabled button",
style: TextStyle(fontSize: 25),
),
disabledColor: Colors.yellow,
disabledTextColor: Colors.black,
)
Eseguendo l’app, potremo vedere un pulsante giallo con scritte in nero come mostrato di seguito.
Figura 90. Bottone disabilitato per a) Android e b) iOS
Altro aspetto interessante per i bottoni è quello di poter definire il testo dei pulsanti in base al tema dell’applicazione sfruttando la proprietà textTheme
. Ad esempio se volessimo usare il tema normal
imposteremo la proprietà come segue.
RaisedButton(
onPressed: () {
print("Button clicked");
},
child: Text(
"Button with textTheme:normal",
style: TextStyle(fontSize: 20),
),
textTheme: ButtonTextTheme.normal
)
Ottenendo il risultato in figura.
Figura 91. Utilizzo del textTheme
per a) Android e b) iOS
Analogamente, se volessimo utilizzare il tema definito per accent
o per primary
basterà sostituire il valore della proprietà textTheme
come segue:
textTheme: ButtonTextTheme.accent
oppure:
textTheme: ButtonTextTheme.primary
Definiamo quindi tre RaisedButton
di cui andiamo a modificare la proprietà textTheme
come mostrato in precedenza, ottenendo il seguente risultato.
Figura 92. Utilizzo del textTheme usando i temi normal, accent, e primary per a) Android e b) iOS
Vediamo ora come utilizzare la proprietà colorBrightness
.
In modo analogo a quanto visto con textTheme
e textColor
, anche questa proprietà permette di modificare e controllare il colore del testo. Ad esempio, utilizzando l’oggetto Brightness
di default possiamo usare la proprietà light
come segue.
RaisedButton(
onPressed: () {
print("Button clicked");
},
child: Text(
"Button with textColor, colorBrightness",
style: TextStyle(
fontSize: 20,
),
),
color: Colors.lightBlue,
colorBrightness: Brightness.light,
)
Eseguendo l’app, otterremo il seguente risultato.
Figura 93. Utilizzo della proprietà colorBrightness per a) Android e b) iOS
È fondamentale ricordare che qualora volessimo usare le proprietà textColor
, textThreme
e colorBrightness
insieme, esiste il seguento livello di precedenze
textColor > textTheme > colorBrightness
Quindi, definendo tutte e tre le proprietà, quella che determina il colore finale del pulsante è textColor
. Un esempio di verifica è reperibile al seguente link.
Con l’introduzione del Material Design, l’elevazione dei pulsanti rispetto al nodo padre è diventata un must sia nelle applicazioni web che mobile. Per implementare questo effetto, il RaisedButton
widget offre le proprietà elevation
e highlightElevation
. Vediamo come usarle nel seguente esempio:
RaisedButton(
onPressed: () {},
child: Text(
"Button with elevation and highlightElevation",
style: TextStyle(fontSize: 20),
),
color: Colors.teal[700],
textColor: Colors.white,
elevation: 5,
highlightElevation: 10,
highlightColor: Colors.lightGreen,
)
In questo esempio abbiamo impostato l’elevazione del bottone a 5
e quando viene premuto a 10
, ottenendo il seguente risultato.
Figura 94. Esempio di utilizzo della proprietà elevation
per a) Android e b) iOS
Analogamente è possibile definire una elevazione quando il pulsante è disabilitato, in modo da renderlo visivamente differente all’utente. Per farlo, dobbiamo utilizzare la proprietà disabledElevation
in combinazione con le precedenti proprietà per disabilitare il pulsante.
Di seguito, è riportato un esempio esplicativo.
RaisedButton(
onPressed: null,
child: Text(
"Button with disabledElevation, Text and Color",
style: TextStyle(fontSize: 20),
),
color: Colors.red[900],
disabledElevation: 10,
disabledTextColor: Colors.black,
disabledColor: Colors.yellow,
)
Visivamente il bottone risulterà come in figura.
Figura 95. Un esempio di RaisedButton disabilitato con utilizzo della proprietà disabledElevation per a) Android e b) iOS
Oltre a quelle viste, un’altra proprietà utile nella definizione di un RaisedButton
è il padding
, con cui abbiamo già preso familiarità nelle precedenti lezioni e di semplice utilizzo, come mostrato in questo esempio.
RaisedButton(
onPressed: () {
print("Button clicked");
},
color: Colors.green,
child: Text(
"Button with padding",
style: TextStyle(fontSize: 20),
),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
)
Qui abbiamo definito un EdgeInsets
tramite il costruttore symmetric
che ci permette di definire la medesima spaziatura dai bordi del pulsante verticalmente e orizzontalmente, come mostrato in figura.
Figura 96. Un esempio di utilizzo della proprietà padding
per a) Android e b) iOS
Chiudiamo infine questa lezione con l’utilizzo della proprietà shape
per dare una forma personalizzata al pulsante della nostra app. Questa proprietà è incredibilmente utile per personalizzare programmaticamente un bottone. Per farlo dobbiamo creare un nuovo oggetto che estenda la classe ShapeBorder
, come ad esempio le classi:
Classe | Descrizione |
---|---|
StadiumBorder |
crea un box rettangolare con dei semicerchi alle estremità |
RoundedRectangleBorder |
definisce un box rettangolare con i bordi arrotondati |
Entrambe le classi definiscono proprietà comuni, come ad esempio la proprietà side
che definisce lo stile del bordo del bottone.
Vediamo quindi un semplice esempio di utilizzo della proprietà shape
con queste due classi per la definizione dei bordi.
RaisedButton(
onPressed: () {
print("Button clicked");
},
color: Colors.teal[700],
child: Text(
"Button with StadiumBorder",
style: TextStyle(fontSize: 20, color: Colors.white),
),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 40),
shape: StadiumBorder(
side: BorderSide(color: Colors.lightGreen, width: 1),
),
),
// . . .
RaisedButton(
onPressed: () {
print("Button clicked");
},
color: Colors.lightGreenAccent,
child: Text(
"Button with rounded rectangle border",
style: TextStyle(fontSize: 20),
),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.black26, width: 4),
borderRadius: BorderRadius.circular(10)),
)
I puksanti così definiti risulteranno essere come quelli rappresentati in figura.
Figura 97. Un esempio di utilizzo della proprietà shape
per a) Android e b) iOS
Il codice di questa lezione è disponibile su GitHub.