Semplificare le animazioni in Flutter con widget animati implicitamente
Le animazioni sono abbastanza facili da fare in Flutter e molta complessità può essere raggiunta con molto meno sforzo rispetto ad Android nativo. Questo si ottiene di solito attraverso modi come la definizione di un’animazione + un AnimationController. Ma ci sono widget incorporati che riducono anche questo e rendono le animazioni facili come cambiare semplicemente dei valori!
Gli esempi completi saranno ospitati sulla mia pagina Github data alla fine di questo articolo.
Un AnimatedContainer passa automaticamente ai valori definiti (colori, dimensioni ecc.) invece di passare istantaneamente ad essi. La GIF data sopra è un esempio di un AnimatedContainer.
Un AnimatedContainer è definito come:
var myColor = Colors.blue;
var myHeight = 100.0;
var myWidth = 100.0;AnimatedContainer(
duration: Duration(seconds: 1),
color: myColor,
height: myHeight,
width: myWidth,
),
In casi normali, dovreste definire un controller e un Tween<double> e un ColorTween per realizzare l’animazione nella GIF sopra. Ma con AnimatedContainer, tutto quello che dovete fare è:
- Impostare una durata per l’animazione
duration: Duration(seconds: 1),
2. Cambiare i valori (cambiare il colore e le dimensioni ai vostri valori)
myColor = Colors.green;
myHeight = MediaQuery.of(context).size.height;
myWidth = MediaQuery.of(context).size.width;
3. SetState()
setState(() {});
Nessun controllore. Nessun Tweens.
Nel momento in cui cambiate i valori di myColor, my Height o myWidth e setState(), il contenitore passa automaticamente ai valori invece di cambiare direttamente a quel valore.
onPressed: () {
myColor = Colors.green;
myHeight = MediaQuery.of(context).size.height;
myWidth = MediaQuery.of(context).size.width;
setState(() {});
}
Al principio, myColor era impostato su Colors.blue. Quando lo cambiamo in Colors.green e setState per ricostruirlo, passa dal blu al verde senza utilizzare alcun Tweens. (Nota: i Tweens sono usati implicitamente ma non hanno bisogno di essere definiti dall’utente.)
Da quello che ho visto, molti sviluppatori non sembrano essere consapevoli di questi widget animati implicitamente e perdono tempo quando non è necessario. Ovviamente ci saranno casi in cui si potrebbe desiderare un diverso tipo di comportamento, ma la maggior parte delle volte, AnimatedContainer fa il lavoro.
Animazioni Hero
Un’animazione Hero fa “volare” un elemento da una pagina alla seconda e lo adatta automaticamente alle dimensioni dello stesso elemento nella seconda pagina. Questo rende qualcosa come una lista in un’app che ha una pagina di dettaglio molto più interessante.
Flutter rende incredibilmente facile implementare animazioni Hero. Tutto quello che dovete fare è avvolgere l’elemento che volete rendere un ‘Eroe’ con un widget Eroe e fornirgli un tag. Se vuoi fare questo in una lista, devi fornire un tag diverso per ogni elemento, che io di solito imposto a “hero” + la posizione dell’elemento nella lista.
L’esempio sopra ha una semplice scheda nella prima pagina con un contenitore con un colore rosso.
Hero(
tag: "heroTag",
child: Container(
color: Colors.red,
height: 100.0,
),
),
Nella pagina dei dettagli, di nuovo c’è un contenitore più grande con un colore rosso pure.
Expanded(
child: Hero(
tag: "heroTag",
child: Container(
color: Colors.red,
),
),
),
E una volta che lo spingo da una pagina all’altra usando
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return new HeroDetailPage();
},
),
);
Ecco!
Il contenitore colorato vola automaticamente e si espande alla dimensione di quest’ultimo.
Poco tempo fa, ho usato un sacco di animazioni in un’app concettuale di scacchi che ho creato con Flutter.
Qui c’è un articolo che ho scritto se volete uno sguardo più dettagliato al codice di questa app.
AnimatedCrossFade
Un CrossFade è una transizione fluida da un widget ad un altro con una data durata. Flutter rende questo facile usando un widget AnimatedCrossFade.
Ecco come viene definito un AnimatedCrossFade:
AnimatedCrossFade(
firstChild: // Your first element here,
secondChild: // Element after transition,
crossFadeState: // State of the transition,
duration: Duration(milliseconds: 1500),
),
Forniamo:
- Il widget prima della transizione
firstChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
height: 200.0,
width: 200.0,
),
2. Il widget dopo la transizione
secondChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FlutterLogo(),
),
height: 100.0,
width: 200.0,
),
3. Lo stato di transizione (Se la transizione è già avvenuta o no)
(Qui, firstStateEnabled è un booleano che possiamo cambiare per cambiare lo stato.)
crossFadeState: firstStateEnabled
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
4. La durata della transizione
duration: Duration(milliseconds: 1500),
Questa quantità di codice è sufficiente per darci l’esempio precedente. La transizione si attiva semplicemente cambiando il crossFadeState.
Nota: Se i due bambini sono di dimensioni diverse, allora si passa automaticamente da una dimensione all’altra.
Ecco una demo:
AnimatedOpacity
AnimatedOpacity anima i cambiamenti di opacità, cioè quanto è visibile un widget.cioè quanto è visibile un widget. Un’opacità di 0 rende un widget completamente trasparente, mentre un’opacità di 1 è completamente visibile.
AnimatedOpacity è dichiarato come:
AnimatedOpacity(
opacity: // Your variable holding opacity value,
duration: // Duration of the transition,
child: FlutterLogo(),
)
Rimanendo simile agli ultimi widget, in AnimatedOpacity, si cambia l’opacità e setState e si anima automaticamente il cambiamento di opacità.
Nell’esempio precedente, è dichiarato come
AnimatedOpacity(
child: FlutterLogo(size: 100.0,),
opacity: myOpacity,
duration: Duration(seconds: 1),
),
Quando il pulsante viene cliccato, cambia semplicemente l’opacità e imposta lo stato.
onPressed: () {
myOpacity = 0.0;
setState(() {});
},