Zjednodušení animací ve Flutteru pomocí implicitně animovaných widgetů


Animace jsou ve Flutteru poměrně snadné a lze jimi dosáhnout velké složitosti s mnohem menším úsilím než v nativním Androidu. Obvykle se toho dosahuje způsoby, jako je definování animace + AnimationController. Existují však vestavěné widgety, které toto ještě snižují a umožňují animaci stejně snadno jako pouhou změnu hodnot!“
Kompletní příklady budou umístěny na mé stránce Github uvedené na konci tohoto článku.

An AnimatedContainer automaticky přechází na definované hodnoty (barvy, velikosti atd.), místo aby se na ně jen okamžitě změnil. Výše uvedený GIF je příkladem AnimatedContainer.
AnimatedContainer je definován jako:
var myColor = Colors.blue;
var myHeight = 100.0;
var myWidth = 100.0;AnimatedContainer(
duration: Duration(seconds: 1),
color: myColor,
height: myHeight,
width: myWidth,
),
V běžných případech byste definovali kontrolér a Tween<double> a ColorTween, abyste dosáhli animace ve výše uvedeném GIFu. Ale s AnimatedContainer stačí udělat:
- Nastavit dobu trvání animace
duration: Duration(seconds: 1),
2. Změnit hodnoty (Změnit barvu a velikost na vaše hodnoty)
myColor = Colors.green;
myHeight = MediaQuery.of(context).size.height;
myWidth = MediaQuery.of(context).size.width;
3. SetState()
setState(() {});
Žádné kontroléry. Žádné Tweens.
V okamžiku, kdy změníte hodnoty myColor, my Height nebo myWidth a setState(), kontejner automaticky přejde na tyto hodnoty, místo aby se změnil přímo na tuto hodnotu.
onPressed: () {
myColor = Colors.green;
myHeight = MediaQuery.of(context).size.height;
myWidth = MediaQuery.of(context).size.width;
setState(() {});
}
Na začátku byla myColor nastavena na Colors.blue. Když ji změníme na Colors.green a pomocí setState ji obnovíme, přejde z modré na zelenou, aniž by se použil nějaký Tweens. (Poznámka: Tweeny se používají implicitně, ale nemusí být definovány uživatelem.)
Podle toho, co jsem viděl, se zdá, že mnoho vývojářů o těchto implicitně animovaných widgetech neví a ztrácí čas, když to není nutné. Samozřejmě se najdou případy, kdy budete chtít jiný druh chování, ale ve většině případů AnimatedContainer splní svou úlohu.
Hero animace

Hero animace způsobí, že prvek z jedné stránky „přeletí“ na druhou a automaticky se přizpůsobí velikosti stejného prvku na druhé stránce. Díky tomu je něco jako seznam v aplikaci, která má stránku s detaily, mnohem zajímavější.
Flutter umožňuje neuvěřitelně snadnou implementaci animací Hero. Jediné, co musíte udělat, je obalit prvek, ze kterého chcete udělat „hrdinu“, widgetem Hero a dodat mu značku. Pokud to chcete provést v seznamu, musíte pro každý prvek dodat jiný tag, který já obvykle nastavuji jen na „hero“ + pozici prvku v seznamu.
Výše uvedený příklad má na první stránce jednoduchou kartu s kontejnerem s červenou barvou.
Hero(
tag: "heroTag",
child: Container(
color: Colors.red,
height: 100.0,
),
),
Na stránce s detailem je opět větší kontejner také s červenou barvou.
Expanded(
child: Hero(
tag: "heroTag",
child: Container(
color: Colors.red,
),
),
),
A jakmile jej přesunu z jedné stránky na druhou pomocí
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return new HeroDetailPage();
},
),
);
To je vše!!!
Barevný kontejner automaticky přelétne a rozšíří se na velikost té druhé.
Před časem jsem spoustu animací použil v koncepční šachové aplikaci, kterou jsem vytvořil pomocí Flutteru.
Tady je článek, který jsem napsal, pokud se chcete podrobněji podívat na kód této aplikace.
AnimatedCrossFade

CrossFade je plynulý přechod z jednoho widgetu na druhý s danou dobou trvání. Flutter to usnadňuje pomocí widgetu AnimatedCrossFade.
Takto se definuje AnimatedCrossFade:
AnimatedCrossFade(
firstChild: // Your first element here,
secondChild: // Element after transition,
crossFadeState: // State of the transition,
duration: Duration(milliseconds: 1500),
),
Dodáváme:
- Widget před přechodem
firstChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
height: 200.0,
width: 200.0,
),
2. Widget po přechodu
secondChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FlutterLogo(),
),
height: 100.0,
width: 200.0,
),
3. Widget po přechodu
secondChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FlutterLogo(),
),
height: 100.0,
width: 200.0,
),
. Stav přechodu (Jestli už k přechodu došlo, nebo ne)
(Zde je firstStateEnabled boolean, který můžeme změnit, abychom změnili stav)
crossFadeState: firstStateEnabled
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
4. Doba trvání přechodu
duration: Duration(milliseconds: 1500),
Toto množství kódu nám stačí na výše uvedený příklad. Přechod se jednoduše spustí změnou stavu crossFadeState.
Poznámka: Pokud mají dvě děti různé velikosti, pak se automaticky přechází z jedné velikosti na druhou.
Tady je ukázka:

AnimatedOpacity

AnimatedOpacity animuje změny krytí, tj.tj. jak je widget viditelný. Při krytí 0 je widget zcela průhledný, zatímco při krytí 1 je zcela viditelný.
AnimatedOpacity se deklaruje jako:
AnimatedOpacity(
opacity: // Your variable holding opacity value,
duration: // Duration of the transition,
child: FlutterLogo(),
)
Podobně jako u několika posledních widgetů, v AnimatedOpacity změníte krytí a setState a automaticky se animuje změna krytí.
V uvedeném příkladu je deklarováno jako
AnimatedOpacity(
child: FlutterLogo(size: 100.0,),
opacity: myOpacity,
duration: Duration(seconds: 1),
),
Při kliknutí na tlačítko se jednoduše změní neprůhlednost a nastaví stav.
onPressed: () {
myOpacity = 0.0;
setState(() {});
},
.