AnimatedPositioned class
지정된 위치가 변경될 때마다 지정된 기간 동안 자식의 위치를 자동으로 전환하는 Positioned 의 애니메이션 버전입니다.
Stack 의 자식인 경우에만 작동합니다.
이 위젯은 애니메이션으로 인해 자식 위젯의 크기가 변경될 경우 좋은 선택입니다. 크기가 동일하게 유지되고 시간 경과에 따라 위치 만 변경되는 경우 SlideTransition을 사용하는 것이 좋습니다. SlideTransition은 애니메이션의 각 프레임마다 리페인팅만 실행하는 반면, AnimatedPositioned는 레이아웃도 실행합니다.
Curves.fastOutSlowIn 곡선을 사용 하여 이 위젯을 사용하는 모습을 보여주는 그림은 다음과 같습니다.
공식 문서 코드
한 번쯤 이런 경험을 해본 적이 있지 않은가? Stack 내부의 코드에서 위치가 이동되는 애니메이션을 넣어 줘야 하는 경우. 심지어 그 위젯의 상위가 Positioned 라면 조금 난감했던 경험이 있을 것이다.
그럴 때에 아주 쉽게 사용할 수 있는 위젯이 이 AnimatedPositioned 위젯이다. 이 위젯은 말 그대로 애니메이션 되는 Positioned 인데 사용법이 아주 간단한데 한번 알아보자.
하위 속성
| 속성명 | 타입 | 기본값 | 설명 |
| child | Widget | – | 애니메이션 위치가 적용될 자식 위젯 |
| left | double? | null | Stack의 왼쪽으로부터의 거리 |
| top | double? | null | Stack의 위쪽으로부터의 거리 |
| right | double? | null | Stack의 오른쪽으로부터의 거리 |
| bottom | double? | null | Stack의 아래쪽으로부터의 거리 |
| width | double? | null | 자식 위젯의 너비 |
| height | double? | null | 자식 위젯의 높이 |
| curve | Curve | Curves.linear | 애니메이션의 진행 곡선 |
| duration | Duration | – | 애니메이션의 총 지속 시간 (필수) |
| onEnd | VoidCallback? | null | 애니메이션 완료 시 호출되는 콜백 |
음 하위 속성을 보면 알겠지만 그냥 Positioned 이다. 거기다가 애니메이션 속성이 3개 추가된 것뿐.
사실 진짜 별거 없다. 그냥 Positioned 쓰는 방법에서 알아서 애니메이션이 추가되는 것뿐이라 기본적으로 Positioned 를 쓸 줄 안다면 1분이면 알 수 있다.
width: selected ? 200 : 50,
height: selected ? 50 : 200,
top: selected ? 50 : 150,
공식 코드에서도 굉장히 쉽게 사용하는데 그냥 위치를 이동할 때에는 흔히들 사용하는 것처럼 삼항연사를 사용해 준다.
원래의 Positioned 라면 그냥 쑥- 하고 순간이동 되어 버리지만 이 위젯은 명색의 애니메이션 위젯 이기 때문에 그 사이에 애니메이션을 추가해준다.
일단 사용법을 알아보자면..
일단 당연하게도 Stack 의 하위에 있어야 할 것이다.
Stack(
children: [
AnimatedPositioned()
],
)
이제 이 위젯은 필수 값으로 Positioned 인 만큼 child 와 애니메이션 위젯이니 duration 을 받고 있다.
AnimatedPositioned(
duration: Duration(milliseconds: 2000),
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: const ColoredBox(color: Colors.blue, child: Center(child: Text('Tap me'))),
),
),
공식 코드에선 듀레이션은 2초 정도로 맞춰 놓았고 child 에는 간단한 컬러박스에 누르면 selected 라는 불리언 값의 변수가 달라지게 만들어 놓았다.
이 불리언 값인 selected 를 통해서 삼항 연산자로 위치 및 크기 치를 바꿔주는 것이다.
width: selected ? 200 : 50,
height: selected ? 50 : 200,
top: selected ? 50 : 150,

그리고 Stack 에다가
alignment: Alignment.center,
이런 걸 사용하고 있다면 조금 주의해야 할 점이 있다. AnimatedPositioned에서 이렇게 중앙정렬을 해주게 되면 수직 위치인 top 또는 bottom 을 직접 설정하지 않고도 중앙 정렬이 가능해진다. 하지만 Possition 에서 했던 것처럼 뇌 빼고 코드 이렇게 작성하면 몇십 줄의 에러 코드를 보게 될 것이다.
top: selected ? 0 : 150,
bottom: 0,
(원래 의도는 이제 top:0, bottom: 0 하면 중앙 정렬 되니까 그거 이용하려 한 거지만 결과는 당연한 실패였다..)
암튼 이렇게 AnimatedPositioned 에 대해서 알아보았다. 이건 생각보다 유용하게 사용할 수 있을 것 같아서 앞으로 도움이 많이 될 수 있을 것 같은 예감이 드는 위젯이다. 도움이 되었길 바라며 마치겠다.