Опростяване на анимациите във Flutter с имплицитно анимирани джаджи

Анимациите са доста лесни за правене във Flutter и много сложност може да бъде постигната с много по-малко усилия от родния Android. Това обикновено се постига чрез начини като дефиниране на Animation + AnimationController. Но има вградени приспособления, които дори намаляват това и правят анимациите толкова лесни, колкото простата промяна на стойности!

Пълните примери ще бъдат хоствани на моята страница в Github, дадена в края на тази статия.

Анимиран контейнер

AnimatedContainer автоматично преминава към дефинираните стойности (цветове, размери и т.н.), вместо просто моментално да ги променя. Даденият по-горе GIF е пример за AnimatedContainer.

AnimatedContainer се дефинира като:

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

В нормални случаи бихте дефинирали контролер и Tween‹double› и ColorTween, за да постигнете анимацията в GIF по-горе. Но с AnimatedContainer всичко, което трябва да направите е:

  1. Задайте продължителност за анимацията
  duration: Duration(seconds: 1),

2. Промяна на стойностите (Промяна на цвета и размера според вашите стойности)

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

3. SetState()

  setState(() {});

Без контролери. Без Tweens.

В момента, в който промените стойностите на myColor, my Height или myWidth и setState(), контейнерът автоматично преминава към стойноститевместо да се променя директно към тази стойност.

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

В началото myColor беше зададен на Colors.blue. Когато го променим на Colors.green и setState, за да го възстановим, той преминава от синьо към зелено, без да използваме Tweens. (Забележка: Tweens се използват имплицитно, но не е необходимо да бъдат дефинирани от потребителя.)

От това, което видях, много разработчици изглежда не са наясно с тези имплицитно анимирани джаджи и губят време, когато не е необходимо. Очевидно ще има случаи, в които може да искате различен вид поведение, но в повечето случаи AnimatedContainer върши работата.

Анимации на герои

Анимацията на Hero кара елемент от една страница да „лети“ към втората и автоматично да се адаптира към размера на същия елемент на втората страница. Това прави нещо като списък в приложение, което има страница с подробности, много по-интересно.

Flutter прави невероятно лесно внедряването на геройски анимации. Всичко, което трябва да направите, е да обвиете елемента, който искате да направите „герой“, с приспособление за герой и да му поставите етикет. Ако искате да направите това в списък, трябва да предоставите различен етикет за всеки елемент, който обикновено задавам на „hero“ + позиция на елемента в списъка.

Горният пример има проста карта на първата страница с контейнер с червен цвят.

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

На страницата с подробности отново има по-голям контейнер с червен цвят.

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

И след като го преместя от една страница на друга с помощта на

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

Това е!

Цветният контейнер автоматично лети и се разширява до размера на последния.

Преди известно време използвах много анимации в концептуално приложение за шах, което създадох с Flutter.

„Ето статия, която написах“, ако искате по-подробен поглед върху кода на това приложение.

AnimatedCrossFade

CrossFade еплавен преход от една джаджа към другас определена продължителност. Flutter прави това лесно с помощта на джаджа AnimatedCrossFade.

Ето как се дефинира AnimatedCrossFade:

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

Ние доставяме:

  1. Приспособлението преди преход
firstChild: Container(
  child: Padding(
    padding: const EdgeInsets.all(8.0),
    child: CircularProgressIndicator(),
  ),
  height: 200.0,
  width: 200.0,
),

2. Приспособлението след преход

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

3. Състоянието на преход (ако преходът вече се е случил или не)

(Тук firstStateEnabled е булево значение, което можем да променим, за да променим състоянието.)

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

4.Продължителност на прехода

duration: Duration(milliseconds: 1500),

Това количество код е достатъчно, за да ни даде горния пример. Преходът просто се задейства чрез промяна на crossFadeState.

Забележка: Ако двете деца са с различни размери, тогава автоматично се преминава от единия към другия размер.

Ето демо:

AnimatedOpacity

AnimatedOpacity анимира промени в непрозрачността, т.е. колко видима е една джаджа. Непрозрачност 0 прави джаджата напълно прозрачна, докато непрозрачност 1 е напълно видима.

AnimatedOpacity се декларира като:

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

Оставайки подобно на последните няколко приспособления, в AnimatedOpacity променяте непрозрачността и setState и това автоматично анимира промяната на непрозрачността.

В горния пример той е деклариран като

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

Когато се щракне върху бутона, той просто променя непрозрачността и задава състояние.

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

Това е всичко за тази статия! Надявам се да ви е харесало и оставете няколко ръкопляскания, ако е така. Последвайте ме за още статии за Flutter и коментирайте всякакви отзиви, които може да имате относно тази статия.

Връзка към Github за примери в тази статия:https://github.com/deven98/AnimatedWidgetsFlutter

Някои от другите ми статии