AnimatedSwitcher class
기본적으로 AnimatedSwitcher 에 자식으로 설정된 위젯과 새 위젯 사이에 크로스 페이드를 수행하는 위젯입니다.
공식 문서 코드
AnimatedSwitcher 는 위젯 간의 전환 애니메이션을 손쉽게 구현할 수 있도록 도와주는 위젯이다. 사용하기 간단하니 한번 알아보자.
하위 속성
| 속성명 | 타입 | 기본값 | 설명 |
| child | Widget? | – | 현재 표시할 자식 위젯 |
| duration | Duration | 필수 | 새 자식 위젯이 들어올 때의 전환 지속 시간 |
| reverseDuration | Duration? | null | 기존 자식 위젯이 사라질 때의 전환 지속 시간 |
| switchInCurve | Curve | Curves.linear | 새 자식이 들어올 때 사용하는 애니메이션 곡선 |
| switchOutCurve | Curve | Curves.linear | 기존 자식이 사라질 때 사용하는 애니메이션 곡선 |
| transitionBuilder | AnimatedSwitcherTransitionBuilder | AnimatedSwitcher.defaultTransitionBuilder | 자식 위젯에 적용할 전환 애니메이션을 정의하는 함수 |
| layoutBuilder | AnimatedSwitcherLayoutBuilder | AnimatedSwitcher.defaultLayoutBuilder | 현재 자식과 이전 자식을 어떻게 배치할지 정의하는 함수 |
기본적인 구성은 이렇게 된다. child 에는 전환할 위젯을 넣어주고 duration 으로 속도 조절을, builder 함수에는 애니메이션을 넣어주면 된다.
AnimatedSwitcher(
duration: Duration(milliseconds: 400),
transitionBuilder: (child, animation) { // child, animation 파라미터를 사용!!
return FadeTransition(opacity: animation, child: child,); // 애니메이션 위젯에 바로 넣기!
},
child: Container(),
)
일단 이름부터 Animated 들어갔으니 또 AnimationController 선언해주고.. 이런 거 할 줄 알았다면 경기도 오산이다. 예제 코드를 보면 알겠지만 애니메이션컨트롤러를 사용하지 않고 AnimatedSwitcher 의 함수인 transitonBuilder 안에 있는 인자값인 animation 을 넣어 주는 모습이다. 각설하고 코드를 봐보자.
(전체코드)
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Test()));
class Test extends StatefulWidget {
const Test({super.key});
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
AnimatedSwitcher(
duration: Duration(milliseconds: 400),
transitionBuilder: (child, animation) {
return FadeTransition(opacity: animation, child: child,);
},
child: Text('$_count', key: ValueKey(_count))),
TextButton(onPressed: () {
setState(() {
_count += 1;
});
}, child: Text('Plus'))
],
),
),
);
}
}
일단 이 위젯을 사용하기 위해선 기본적으로 Stateful 인 상태여야 한다. 당연하게도 이 상태로 해놔야 애니메이션이 적용이 되니 말이다. 일단 나도 공식 예제를 따라서 만들어 보았는데 이게 젤 쉬운 느낌이 들어서 그랬다.
만든 것은 숫자가 바뀌면 간단한 Fade 애니메이션이 들어가는 거다.
먼저 사용할 int 변수를 하나 만들어주겠다.
int _count = 0;
이제 이걸로 텍스트에 표시하고 key 에 넣어줄 것이다.
AnimatedSwitcher(
duration: Duration(milliseconds: 400),
transitionBuilder: (child, animation) {
return FadeTransition(opacity: animation, child: child,);
},
child: Text('$_count', key: ValueKey(_count))),
그 후에 바로 AnimatedSwitcher 를 사용했는데 조금씩 뜯어서 설명하겠다.
먼저 duration, 뭐 이건 모를 거라 생각하지 않는다. 자신이 원하는 실행 시간을 Duration 으로 조절해줄 수 있다.
duration: Duration(milliseconds: 400),
그다음은 빌더 함수인 transitionBuilder 이다.
transitionBuilder: (child, animation) {
return FadeTransition(opacity: animation, child: child,);
},
빌더 함수인만큼 파라미터를 주는데 이거를 두 개 다 사용할 것이다.
일단 지금 나는 여기서 간단한 Fade애니메이션을 줄 수 있는 FadeTrandsition 을 주고 있다. 이 위젯은 아규먼트로 opacity 값을 받는데 여기다가 그냥 위에서 주는 aniamtion 파라미터 넣어주면 된다. 그런 후 직접 child 를 추가해서 child 파라미터를 넣어줘야 한다.
이렇게 넣어주는 이류를 짚고 가겠다.
transitionBuilder는 다음 두 인자를 받는다.
- child: 전환 대상 새 위젯
- animation: 0.0 ~ 1.0 사이로 변화하는 Animation<double>
이 두 개를 받아서 이렇게 만들었으니
FadeTransition(opacity: animation, child: child,);
animation 값이 0 -> 1로 증가하면서 child 위젯의 투명도(opacity)도 0 -> 1로 변화하게 된다. 이렇게 되면서 fade 효과가 나타는 것이다.
다시 말해 이 코드는 새로 보여줄 위젯(child)을 FadeTransition 안에 넣는 것이고, 이로 인해 AnimatedSwitcher 가 새 위젯으로 전환할 때 애니메이션을 적용하는 코드라는 것이다.
이제 중요하다. 이 AnimatedSwicher 위젯은 어쨌든 간에 위젯끼리 서로 전환하는 효과를 주는 위젯인데 어떠한 위젯끼리 전환되는지를 알 수 있어야 한다. 그래서 key 를 무조건 넣어줘야 한다.
child: Text('$_count', key: ValueKey(_count))),
그냥 count 변수를 표시하는 텍스트이지만 key 를 넣어서 고유한 번호를 부여해줬다. 이렇게 key 를 넣게 되면 count 값이 바뀔 때마다 새로운 key 가 텍스트에 부여되기 때문에 계속해서 애니메이션을 적용시켜 줄 수 있는 것이다.
밑에는 그냥 평범하게 버튼 누르면 count 값 올라게 만들었다.
TextButton(onPressed: () {
setState(() {
_count += 1;
});
}, child: Text('Plus'))
이해가 안 됐을 이들을 위해 더 쉬운 예제도 준비해 놨다.
class _TestState extends State<Test> {
bool _toggle = true;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AnimatedSwitcher(
duration: Duration(milliseconds: 500),
transitionBuilder: (child, animation) => ScaleTransition(scale: animation, child: child),
child: _toggle
? Container(
key: ValueKey(1),
width: 100,
height: 100,
color: Colors.blue,
)
: Container(
key: ValueKey(2),
width: 100,
height: 100,
color: Colors.red,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => _toggle = !_toggle),
child: Icon(Icons.swap_horiz),
),
);
}
}
이 코드를 보면 이제 직관적으로 이해가 될 것이다.
암튼 이렇게 AnimatedSwitcher 에 대해서 알아보았다. 이번엔 진짜 간단하게 구성해 보았는데 도움이 되었으면 좋겠다. 그럼 마치겠다.