Impliciet geanimeerde Widgets in Flutter

Vereenvoudigen van animaties in Flutter met Impliciet geanimeerde Widgets

Deven Joshi
Deven Joshi

Follow

12 okt, 2018 – 5 min read

Animaties zijn vrij eenvoudig te doen in Flutter en veel complexiteit kan worden bereikt met veel minder inspanning dan native Android. Dit wordt meestal bereikt door manieren zoals het definiëren van een Animatie + een AnimationController. Maar er zijn ingebouwde widgets die dit zelfs verminderen en animaties zo eenvoudig maken als het simpelweg veranderen van waarden!

De volledige voorbeelden zullen worden gehost op mijn Github pagina die aan het eind van dit artikel wordt gegeven.

Een AnimatedContainer in Flutter

Een AnimatedContainer gaat automatisch over naar de gedefinieerde waarden (kleuren, groottes etc.) in plaats van alleen maar ogenblikkelijk te veranderen naar deze waarden. De bovenstaande GIF is een voorbeeld van een AnimatedContainer.

Een AnimatedContainer wordt gedefinieerd als:

var myColor = Colors.blue;
var myHeight = 100.0;
var myWidth = 100.0;AnimatedContainer(
duration: Duration(seconds: 1),
color: myColor,
height: myHeight,
width: myWidth,
),

In normale gevallen zou u een controller en een Tween<double> en een ColorTween definiëren om de animatie in de bovenstaande GIF te bereiken. Maar met AnimatedContainer hoeft u alleen maar:

  1. Een duur voor de animatie instellen
 duration: Duration(seconds: 1),

2. Waarden wijzigen (kleur en grootte naar uw waarden wijzigen)

 myColor = Colors.green;
myHeight = MediaQuery.of(context).size.height;
myWidth = MediaQuery.of(context).size.width;

3. SetState()

 setState(() {});

Geen controllers. Geen Tweens.

Op het moment dat je de waarden van mijnKleur, mijnHoogte of mijnBreedte en setState() verandert, gaat de container automatisch over naar de waarden in plaats van direct naar die waarde te veranderen.

onPressed: () {
myColor = Colors.green;
myHeight = MediaQuery.of(context).size.height;
myWidth = MediaQuery.of(context).size.width;
setState(() {});
}

Aan het begin was mijnKleur ingesteld op Colors.blue. Wanneer we het veranderen in Colors.green en setState om het opnieuw op te bouwen, gaat het over van blauw naar groen zonder dat er Tweens worden gebruikt. (Opmerking: Tweens worden impliciet gebruikt, maar hoeven niet door de gebruiker te worden gedefinieerd.)

Van wat ik heb gezien, lijken veel ontwikkelaars zich niet bewust te zijn van deze impliciet geanimeerde widgets en verspillen tijd als het niet nodig is. Uiteraard zullen er gevallen zijn waarin je een ander soort gedrag wilt, maar meestal voldoet AnimatedContainer.

Hero-animaties

Hero-animaties in Flutter

Een Hero-animatie laat een element van de ene pagina naar de tweede “vliegen” en zich automatisch aanpassen aan de grootte van hetzelfde element op de tweede pagina. Dit maakt iets als een lijst in een app met een detailpagina veel interessanter.

Flutter maakt het ongelooflijk eenvoudig om Hero-animaties te implementeren. Het enige wat je hoeft te doen is het element dat je een ‘Hero’ wilt maken omwikkelen met een Hero widget en er een tag aan toe te voegen. Als je dit in een lijst wilt doen, moet je voor elk element een andere tag leveren, die ik gewoon meestal instel op “hero” + positie van element in de lijst.

Het bovenstaande voorbeeld heeft een eenvoudige kaart op de eerste pagina met een container met een rode kleur.

Hero(
tag: "heroTag",
child: Container(
color: Colors.red,
height: 100.0,
),
),

Op de detailpagina staat weer een grotere container met ook een rode kleur.

Expanded(
child: Hero(
tag: "heroTag",
child: Container(
color: Colors.red,
),
),
),

En zodra ik het van de ene pagina naar de andere duw met

Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return new HeroDetailPage();
},
),
);

Dat is het!

De gekleurde container vliegt automatisch en breidt zich uit naar de grootte van de laatste.

Een tijdje geleden heb ik veel animaties gebruikt in een concept schaak app die ik met Flutter heb gemaakt.

Hier is een artikel dat ik heb geschreven als je een meer gedetailleerde blik op de code van deze app wilt werpen.

AnimatedCrossFade

AnimatedCrossFades in Flutter

Een CrossFade is een vloeiende overgang van de ene widget naar de andere met een bepaalde duur. Flutter maakt dit eenvoudig met behulp van een AnimatedCrossFade widget.

Zo wordt een AnimatedCrossFade gedefinieerd:

AnimatedCrossFade(
firstChild: // Your first element here,
secondChild: // Element after transition,
crossFadeState: // State of the transition,
duration: Duration(milliseconds: 1500),
),

We leveren:

  1. De widget voor de overgang
firstChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
height: 200.0,
width: 200.0,
),

2. De widget na de overgang

secondChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FlutterLogo(),
),
height: 100.0,
width: 200.0,
),

3. De toestand van de overgang (Is de overgang al gebeurd of niet)

(Hier is firstStateEnabled een boolean die we kunnen veranderen om de toestand te veranderen.)

crossFadeState: firstStateEnabled
? CrossFadeState.showFirst
: CrossFadeState.showSecond,

4. De duur van de overgang

duration: Duration(milliseconds: 1500),

Deze hoeveelheid code is voldoende om ons het bovenstaande voorbeeld te geven. De overgang wordt eenvoudig getriggerd door de crossFadeState te veranderen.

Note: Als de twee kinderen van verschillende grootte zijn, dan gaat hij automatisch van de ene grootte over naar de andere.

Hier is een demo:

AnimatedOpacity

AnimatedOpacity animeert veranderingen in opacity, d.d.w.z. hoe zichtbaar een widget is. Een opacity van 0 maakt een widget volledig transparant, terwijl een opacity van 1 volledig zichtbaar is.

AnimatedOpacity wordt gedeclareerd als:

AnimatedOpacity(
opacity: // Your variable holding opacity value,
duration: // Duration of the transition,
child: FlutterLogo(),
)

Gelijk aan de laatste paar widgets, in AnimatedOpacity, verander je de opacity en setState en het animeert automatisch de verandering in opacity.

In het bovenstaande voorbeeld wordt het gedeclareerd als

AnimatedOpacity(
child: FlutterLogo(size: 100.0,),
opacity: myOpacity,
duration: Duration(seconds: 1),
),

Wanneer op de knop wordt geklikt, verandert het eenvoudig de opaciteit en stelt de status in.

onPressed: () {
myOpacity = 0.0;
setState(() {});
},

Plaats een reactie