•
Flutter는 1초에 60번 update를 한다. 즉 animation은 1회 rendering에 16milliseconds가 걸리는 것이다. 이를 처리하기 위해서 SingleTickerProviderStateMixin이 필요하다. 이를 이용하면, Widget에게 animation에 의해서 frame update가 일어남을 알리게 된다.
•
Animation 생성 방법
•
AnimationController와 Animation<T>가 필요하다. (initState()에서 처리한다.)
•
Controller는 vsync를 this로 해주고 duration을 설정한다.
•
Animation Class의 instance는 두 frame 사이에 어떻게 animate해야 하는지 가이드 하기 위해 Tween class로 초기화 되어야 한다. (Tween의 타입은 Animaton<T>로 준 타입과 동일하다.)
•
Tween<T>(begin:, end:,).animate()
•
애니메이션 효과를 내고 싶은 인자에 생성한 animate의 값을 입힌다.
•
이후 animation이 바뀌는 곳에 controller.forward() 혹은 controller.reverse()를 해준다.
•
그럼 지금까지 한 것이 controller를 생성하고, animation의 크기 값과 효과 선택, 그리고 animation 크기 값과 효과를 할당한 것이다.
•
마지막으로 animation에 Listener를 달아야 한다. (initState()부분) 만일 manual하게 listener작업하기 싫다면, AnimatedBuilder라는 Widget을 통해서 자동으로 생성할 수도 있다.
•
animation을 생성 후에는 controller를 소멸시키는 dispose()를 정의해야 한다. (생성이든 소멸이든 둘다 super.() 다음에 해줘야 한다.)
•
responsive UI를 쓴다면 constraints의 minHeight도 animation값을 줘야 한다.
•
위 방법처럼 이렇게 일일이 Animation을 주는 것 마저도 귀찮다면 AnimatedContainer() Widget을 이용하면 된다. (state관리 및 re-rendering여부를 manual하게 하는 것보다 훨씬 효율적이다.)
•
AnimatedContainer()은 많은 일을 줄여주는 Widget이며, 효율적으로 동작하고 자동으로 transition을 만들어 준다.
•
두 값이 주어지면 자동으로 이를 인식하여 두 값에 대해서 smooth하게 처리하는 모션을 보인다.
•
따라서 controller에 listener를 달아서 쓰는 방법과 AnimatedBuilder와 같이 animation 크기 값을 직접 지정하지 않고 원래 Container에 쓰는 것처럼 상수 값을 주면 알아서 인식하고 animation을 적용 해준다.
•
또한 변화하는 값에 따라 알아서 forward(), reverse()를 처리하기 때문에 수동으로 controller을 만들어서 쓸 필요도 없을 뿐더러 animation 크기 값을 선택할 필요 없이 인자로 duration과 curve만 주면 된다.
•
이외에도 멋지고 강력한 Widget들이 많다. 예를 들면, FadeTransition과 같은 if문을 없앨 수 있는 Widget들도 존재한다.
** animation간 nested로 이용하게 되면 굉장히 느려질 수 있다.
•
Hero의 tag는 새로운 창이 앞으로 나오면서 커지는 animation을 나타낼 때 어떤 어떤 Screen을 animating 할지 구분하기 위한 용도이다. 따라서 어떠한 값이든 unique한 값이면 된다. 또한 두 스크린 간 switching으로 이뤄지는 animation이기 때문에 Hero Widget은 Before Screen, After Screen 두 Screen에 모두 같은 tag로 걸어야 한다.
•
Scaffold내 body에 CustomScrollView로 줘서 AppBar와 Image간 이쁜 animation을 넣을 수 있다.
•
이 때 기존 AppBar는 지워야 한다.
•
slivers로 SliverList와 SliverAppBar로 넣는데 SliverList는 일종의 ListView이다.
•
SliverList의 인자로 쓰이는 delegate는 List안에 요소들을 어떻게 Render해야할지 알리는 역할을 한다.
•
SliverAppBar의 인자로 들어가는 expandedHeight는 AppBar을 제한 높이이며, pinned는 scroll시 AppBar을 보일지 말지에 대한 인자, flexibleSpace는 AppBar내의 Animating 시킬 공간의 인자이다.
•
Page Routing에 직접 animation을 주고 싶다면 CustomRoute<T> class를 만들어 주고, 이 때MaterialPageRoute<T>를 상속 받게 한다. (push or push replace, but not push named)
•
만든 class에서 인자로 가져야 하는 것은 Widget을 만드는 WidgetBuilder와 MaterialPageRoute가 갖는 settings인자 타입인 RouteSetting가 필요하다. (즉, MaterialPageRoute가 받는 것들을 기본적으로 모두 처리할 수 있어야 한다.) 이렇게 설정된 값들은 Parent Class로 보내야 해서 :을 이용하여 super class로 보낸다. (:의 의미는 initializer이다.)
•
또한 buildTransition이 필요하므로 super class의 것을 override 한다. 여기서 <RouterSettings>.isInitialRoute 처리는 첫 화면에는 animation을 넣지 않기 위한 것이다.
•
마지막으로 이런 CustomRoute를 적용하기 위해 theme에 pageTransitionsTheme을 지정해야 한다. 이 Theme에는 각 platform에 맞는 transitionBuilder가 필요하다. 따라서 PageTransitionsBuilder를 상속하는 새로운 class CustomPageTransitionsBuilder을 생성 해준다. 이전에 만든 CustomRoute를 Generic타입의 buildTransition()의 인자로 준다. platform에 해당하는 transition builder지정한다.