Animator는 애니메이션 로직을 사용자 인터페이스에서 분리하여 애니메이션 개발을 단순화하도록 설계된 Flutter 라이브러리입니다. 개발자는 애니메이션을 독립적으로 정의할 수 있어 코드를 더 모듈화하고 유지보수하기 쉽게 만들 수 있습니다. 명확한 분리 덕분에 다양한 위젯과 화면 간에 애니메이션을 중복 설정 코드 없이 재사용할 수 있습니다. 이 라이브러리는 Android, iOS, Web, macOS, Windows, Linux 등 모든 주요 플랫폼을 지원하며, 다양한 환경에서 일관된 동작을 보장합니다. 복잡하거나 반복적인 애니메이션이 필요한 프로젝트에 적합합니다.
사용 사례
여러 위젯 간에 애니메이션 로직 재사용
UI 컴포넌트에서 부드러운 전환 만들기
재사용 가능한 애니메이션 요소 만들기
복잡한 애니메이션 시퀀스 간소화
다중 플랫폼 앱에서 반응형 애니메이션 구현
주요 기능
애니메이션 설정과 UI의 분리
크로스 플랫폼 호환성
재사용 가능한 애니메이션 정의
모든 플러터 플랫폼 지원
깔끔한 선언형 애니메이션 구문
적합한 대상
더 깔끔한 애니메이션 코드를 원하는 개발자
자주 발생하거나 복잡한 애니메이션을 포함하는 프로젝트
코드 모듈화를 우선시하는 팀
다중 플랫폼 Flutter 애플리케이션
동적 상호작용을 갖춘 UI 중심 앱
고려 사항
Flutter의 애니메이션 시스템에 대한 이해가 필요합니다
간단한 애니메이션에 약간의 오버헤드를 추가할 수 있습니다
중대규모 프로젝트에 가장 적합
기본 예제 외에 문서가 제한적
단발성, 간단한 애니메이션에 적합하지 않음
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
animator
This library is an animation library for Flutter that:
makes animation as simple as the simplest widget in Flutter with the help of Animator widget,
Allows you to control (forward, stop, inverse), reconfigure, reset and restart animation from buttons, or events callbacks.
Perform implicit and explicit animation without limitation.
This library exposes two widgets, Animator, ane AnimateWidget
Animator is the first introduced widget. It allows for explicit animation.
AnimateWidget the the new widget which is more powerful than Animator. It is used for both implicit animation and explicit and staggered animation.
AnimateWidget
setting animation parameters
AnimateWidget exposes the following parameters to set your animation:
(1) Optionally you can set the initialValue, lowerBound, upperBound to be taken by the AnimationController.
(2) duration and reverseDuration are the global (default) durations of the animation in the forward and reverse path. If reverseDuration is not set (or is null) the value of duration will be used for both forward and reverse path. The value of duration and reverseDuration can be overridden for any value. (see later).
(3) curve and reverseCurve are the global (default) curves of the animation in the forward and reverse path. If reverseCurve is not set (or is null) the value of curve will be used for both forward and reverse path. The value of curve and reverseCurve can be overridden for any value. (see later).
(4) animationBehavior has similar meaning as in Flutter animationBehavior (The behavior of the controller when AccessibilityFeatures.disableAnimations is true).
With cycles argument (5) you define the number of the forward and backward periods you want your animation to perform before stopping.
With repeats argument (5) you define the number of forward periods you want your animation to perform before stopping.
With endAnimationListener (6) argument you can define a VoidCallback to be executed when the animation is finished. For example, it can be used to trigger another animation.
You can control when animation starts (7) using :
triggerOnInt: When set to true, animation will auto start after first initialized. The default value is true.
triggerOnRebuild: When set to true, animation will try to trigger on rebuild. If animation is completed (stopped at the upperBound) then the animation is reversed, and if the animation is dismissed (stopped at the lowerBound) then the animation is forwarded. IF animation is running nothing will happen. Default value is false.
resetOnRebuild: When set to true, animation will reset and restart from its lowerBound.
In the builder argument (8) you put your widgets to be animated.
AnimateWidget(
builder : (BuildContext context, Animate animate) {
//Implicit animationfinal T value = animate.call(select? 0 : 100);
///Two value of the same type must be distinguished using an arbitrary namefinal T otherValue = animate.call(select? 0 : 100, 'Other value');
//Explicit animationfinal T value = animate.fromTween((currentValue)=> Tween(begin:0, end: 100));
//Use predefined flutter FooTransition widgetScaleTransition(
scale : animate.curvedAnimation
child: ...
)
},
child : MayWidget(), //widget to not rebuild with animation
)
Implicit animation
With animator you can do any kind of implicit animation without been constrained to fined a dedicated Flutter widget of type AnimatedFoo such as AnimatedContainer, AnimatedPositioned and so on.
Let's reproduce the AnimatedContainer example in official Flutter docs. (link here).
Using the exposed animate function, we set the animation start and end values.
As the width and height are the same type (double), we need to add a name to distinguish them.
You can implicitly animate any type. Here we implicitly animated a double, Color, and Alignment values. If you want to animate two parameters of the same type, you just add a dummy name to distinguish them.
That's all, you are not limited to use a widget that starts with Animated prefix to use implicit animation.
To implement any type of animation with animator you have to define a Tween (1), Duration (2), and Curve (3). `
With cycles argument (4) you define the number of the forward and backward periods you want your animation to perform before stopping.
With repeats argument (5) you define the number of forward periods you want your animation to perform before stopping.
In the builder argument (6) you put your widgets to be animated.
Animator<T>(
builder : (BuildContext context, AnimatorState animatorState, Widget child) {
//to get animation value:final T value = animatorState.value;
//to get Animation object:finalAnimation<T> animation = animatorState.animation;
//to get AnimationController object:finalAnimationController animation = animatorState.controller;
//to get animation value form tweenMapfinal R value = animatorState.getValue<R>('animName');
//To get Animation object from tweenMapfinalAnimation<R> value =animatorState.getAnimation<R>('animName');
},
child : MayWidget(), //widget to not rebuild with animation
)
If you want to animate many Tween, use tweenMap argument (2). It is a Map of String type keys and Tween type values.
With endAnimationListener (8) argument you can define a VoidCallback to be executed when the animation is finished. For example, it can be used to trigger another animation.
With customListener (9) argument you can define a function to be called every time the animation value changes. The customListener is provided with an Animation object.
With statusListener (10) argument, you can define a function to be called every time the status of the animation change. The customListener is provided with an AnimationStatus, AnimationSetup objects.
triggerOnInit (11) controls whether the animation is automatically started when the Animator widget is initialized. The default value is true.
If you want to reset your animation, such as changing your Tween or duration, and want the new setting to be reconsidered when the Animator widget is rebuilt, set the resetAnimationOnRebuild (12) argument to true. The default value is false. (See AnimatorKey)
The right TickerProvider is chosen by animator:(13)
If animation is simple the singleTickerProviderStateMixin.
If you define the animatorKey parameter or set resetAnimationOnRebuild, animator use tickerProviderStateMixin.
With animationKey (14), you can associate an Animator widget to an AnimatorKey. Doing so, you can control (forward, start, stop, reverse) animation from callbacks outside the Animator widget, you can even reset the animation parameter (tween, duration curve, repeats, cycles) on the fly. (See example below)
Use nested Animators with CustomPainter and CustomClipper and draw the animation you want.
AnimatorKey
Similarly to Flutter global key. AnimatorKey allows controlling the animation from outside the Animator widget it is associated with.
Example:
final animatorKey = AnimatorKey();
//..//..Animator(
animatorKey: animatorKey,
builder: (context, anim, child) {
//....
}
)
//By default, the animation will not start when the Animator is inserted in the widget tree.//To start the animation from some Button in the widget tree outside the builder of the Animator.
onPressed: (){
animatorKey.triggerAnimation();
//You can forward, start, reverse animation
animatorKey.controller.stop,
//You can configure the animation online and reset the setting and restart the animation
animatorKey.refreshAnimation(
tween: Tween(...),//new tween
duration : Duration(...),
curve : Curve(...),
repeats : ....,
cycles : ...
);
}
AnimatorRebuilder widget
The AnimatorRebuilder widget can subscribe to an “AnimatorKey”. It will be animated in synchronization with the Animator widget with which animatorKey is associated.
Example:
//In AnimatorKey you can provide the initial values of the animation.final animatorKey = AnimatorKey<T>(initialValue: 10);
//..//..Animator(
animatorKey: animatorKey,
builder: (context, anim, child) {
//....
}
);
////In another place in the widget tree : AnimatorRebuilder(
observe:()=> animatorKey,
builder: (context, anim, child) {
//....//this widget receives the same animation object of the Animator above.
}
);
The order of Animator and AnimatorRebuilder in the widget tree is irrelevant, except in the case, AnimatorRebuilder is first inserted in the widget tree, you have to provide initial values in AnimatorKey to avoid null exceptions.