Implicit módon animált widgetek a Flutterben

Az animációk egyszerűsítése a Flutterben implicit módon animált widgetekkel

Deven Joshi
Deven Joshi

Follow

okt. 12, 2018 – 5 min read

A Flutterben elég könnyű animációkat készíteni, és sok komplexitást lehet elérni sokkal kevesebb erőfeszítéssel, mint a natív Androidban. Ez általában olyan módszerekkel érhető el, mint például egy Animation + egy AnimationController definiálása. De vannak beépített widgetek, amelyek még ezt is csökkentik, és az animációkat olyan egyszerűvé teszik, mint az értékek egyszerű megváltoztatása!

A teljes példák a cikk végén megadott Github oldalamon lesznek elhelyezve.

Egy AnimatedContainer a Flutterben

Egy AnimatedContainer automatikusan átvált a definiált értékekre (színek, méretek stb.) ahelyett, hogy csak úgy azonnal átváltana rájuk. A fenti GIF egy példa egy AnimatedContainerre.

Egy AnimatedContainer a következőképpen definiálható:

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

Rendes esetben egy vezérlőt és egy Tween<double> és egy ColorTween-t definiálnánk a fenti GIF-ben látható animáció eléréséhez. De az AnimatedContainerrel csak annyit kell tenned, hogy:

  1. Meghatározod az animáció időtartamát
 duration: Duration(seconds: 1),

2. Megváltoztatod az értékeket (Szín és méret megváltoztatása az értékeidre)

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

3. SetState()

 setState(() {});

Nincs vezérlő. Nincs Tweens.

Amikor megváltoztatja a myColor, my Height vagy myWidth és a setState() értékeit, a konténer automatikusan átvált az értékekre, ahelyett, hogy közvetlenül az adott értékre váltana.

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

Az elején a myColor Colors.blue értékre volt állítva. Amikor megváltoztatjuk Colors.green-re, és a setState funkcióval újra felépítjük, a kékről zöldre vált át, anélkül, hogy bármilyen Tweent használnánk. (Megjegyzés: A Tweens implicit módon használatos, de nem kell felhasználó által definiálni.)

Az általam látottak alapján úgy tűnik, hogy sok fejlesztő nincs tisztában ezekkel az implicit módon animált widgetekkel, és időt pazarolnak, amikor nincs rá szükség. Nyilván lesznek olyan esetek, amikor másfajta viselkedést szeretnél, de a legtöbbször az AnimatedContainer elvégzi a dolgát.

Hero animációk

Hero animációk a Flutterben

A Hero animációval egy elem az egyik oldalról “átrepül” a második oldalra, és automatikusan igazodik ugyanannak az elemnek a méretéhez a második oldalon. Ez sokkal érdekesebbé tesz valamit, például egy listát egy olyan alkalmazásban, amelynek van egy részletes oldala.

A Flutterrel hihetetlenül egyszerűen megvalósíthatók a Hero animációk. Mindössze annyit kell tennie, hogy a “hőssé” tenni kívánt elemet becsomagolja egy Hero widget-tel, és ellátja egy címkével. Ha ezt egy listában akarod megtenni, akkor minden egyes elemhez más taget kell megadnod, amit én általában csak “hero” + az elem pozíciója a listában.

A fenti példában egy egyszerű kártya van az első oldalon egy piros színű konténerrel.

A részletoldalon megint van egy nagyobb konténer, szintén piros színnel.

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

És amint az egyik oldalról a másikra tolom a

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

segítségével

Ez az!

A színes konténer automatikusan repül és kitágul az utóbbi méretére.

Egy ideje sok animációt használtam egy koncepciós sakk alkalmazásban, amit Flutterrel készítettem.

Itt van egy cikk, amit írtam, ha szeretnéd részletesebben megnézni ennek az alkalmazásnak a kódját.

AnimatedCrossFade

AnimatedCrossFades in Flutter

A CrossFade egy adott időtartamú, sima átmenet egyik widgetről a másikra. A Flutter megkönnyíti ezt egy AnimatedCrossFade widget segítségével.

Így definiáljuk az AnimatedCrossFade-et:

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

A következőket adjuk meg:

  1. A widget az átmenet előtt
firstChild: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
height: 200.0,
width: 200.0,
),

2. A widget az átmenet után

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

3. Az átmenet után

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

. Az átmenet állapota (Ha az átmenet már megtörtént vagy sem)

(Itt a firstStateEnabled egy boolean, amit megváltoztathatunk az állapot megváltoztatásához)

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

4. Az átmenet időtartama

duration: Duration(milliseconds: 1500),

Ez a mennyiségű kód elég a fenti példához. Az átmenetet egyszerűen a crossFadeState változása váltja ki.

Megjegyzés: Ha a két gyermek különböző méretű, akkor automatikusan átmegy az egyik méretről a másikra.

Itt egy demó:

AnimatedOpacity

AnimatedOpacity animálja az átlátszóság változását, ill.Vagyis, hogy mennyire látható egy widget. A 0 opacitás teljesen átlátszóvá teszi a widgetet, míg az 1 opacitás teljesen láthatóvá teszi.

Az AnimatedOpacity a következőképpen van deklarálva:

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

Az előző widgetekhez hasonlóan az AnimatedOpacity-ben is megváltoztatjuk az opacitást és a setState-et, és az automatikusan animálja az opacitásváltozást.

A fenti példában így van deklarálva:

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

A gombra kattintáskor egyszerűen megváltoztatja az opacitást és beállítja az állapotot.

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

Szólj hozzá!