AnimatedList class
항목을 삽입하거나 제거할 때 해당 항목에 애니메이션을 적용하는 스크롤 컨테이너입니다.
이 위젯의 AnimatedListState를 사용하여 항목을 동적으로 삽입하거나 제거할 수 있습니다. AnimatedListState 를 참조하려면 GlobalKey를 제공 하거나 항목의 입력 콜백에서 정적 메서드 of 를 사용하세요.
이 위젯은 ListView.builder 로 만든 위젯과 비슷합니다.
공식 문서 코드
AnimatedList 는 리스트를 애니메이션과 함께 보여줄 수 있게 해주는 위젯이다. ListView 같은 위젯은 항목(아이템)을 추가하거나 제거할 때 애니메이션을 적용하지 않지만 이 위젯을 사용하면 넣고 싶은 애니메이션을 넣어줄 수 있다.
기본적으로 리스트 답게 itemBuilder 를 가지고 있는데 빌더 함수에 애니메이션이 들어가 있다.
또한 GlobalKey<AnimatedListState> 를 통하여 리스트에 항목을 삽입하거나 제거하는 것에 애니메이션을 넣어줄 수도 있다.
한번 간단하게 알아보자.
하위 속성
| 속성명 | 타입 | 기본값 | 설명 |
| itemBuilder | AnimatedItemBuilder | – | 애니메이션과 함께 각 항목을 생성하는 함수 |
| initialItemCount | int | 0 | 초기 리스트에 표시할 항목의 개수 |
| scrollDirection | Axis | Axis.vertical | 리스트의 스크롤 방향 (수직 또는 수평) |
| reverse | bool | false | 리스트를 역방향으로 표시할지 여부 |
| controller | ScrollController? | null | 스크롤 위치를 제어하기 위한 컨트롤러 |
| primary | bool? | null | 기본(primary) 스크롤 보기로 설정할지 여부 |
| physics | ScrollPhysics? | null | 스크롤 동작 방식 설정 |
| shrinkWrap | bool | false | 자식의 크기만큼만 리스트 크기를 설정할지 여부 |
| padding | EdgeInsetsGeometry? | null | 리스트 안쪽 여백 설정 |
| clipBehavior | Clip | Clip.hardEdge | 자식이 부모 위젯을 넘어갈 때 처리 방식 |
공식 문서 코드
일단 당연하게도 리스트이기때문에 itemBuilder 를 받아야 한다.
itemBuilder: (context, index, animation) {
빌더를 만들면 이런 빌더함수가 나올텐데 주목해야 할것은 animation 이 되겠다. 이걸 사용해서 아래에 애니메이션이 들어갈자리에 그냥 톡하고 넣어주면 되는 아주 쉬운 인자값이다.
그다음 가장 중요한것은 당연하게도 key 일텐데 여기에다간 글로벌키를 만들고 넣어주면 되겠다. 간단하게 이렇게 만들어보자.
final GlobalKey<AnimatedListState> _listKey = GlobalKey();
이러면 key 만드는 것도 끝났다.
key: _listKey,
그럼 이제 이 위젯을 사용하는 주 목적인 추가/제거 시 애니메이션을 넣는 방법은 무엇일까? 방금 만든 key, 글로벌 키를 사용하면 되겠다.
가벼운 사용법을 봐보자.
final List<String> _items = ['Item 1', 'Item 2', 'Item 3'];
void _addItem() {
final newItem = 'Item ${_items.length + 1}';
_items.insert(0, newItem); // insert
_listKey.currentState!.insertItem(0);
}
void _removeItem(int index) {
final removedItem = _items.removeAt(index); // remove
_listKey.currentState!.removeItem(
index,
(context, animation) => SizeTransition(
sizeFactor: animation,
child: ListTile(title: Text(removedItem)),
),
);
}
먼저 리스트 하나를 초기값을 설정해주고 만들어준다. (initialItemCount 용)
final List<String> _items = ['Item 1', 'Item 2', 'Item 3'];
그런 후 먼저 새로운 항목을 추가 하는 메서드를 하나 만들어줄 것인데 그 안에서 먼저 리스트에 추가할 새 항목을 생성해줘야 한다.
final newItem = 'Item ${_items.length + 1}'; // 리스트에 추가될 새 항목 생성
그 후 리스트에 새항목을 삽입해주는 동작을 만들어주고 AnimatedListState 을 사용하여 애니메이션을 넣어주면 되겠다.
_items.insert(0, newItem); // 새 항목을 리스트의 맨 앞(0번째 인덱스)에 삽입
_listKey.currentState!.insertItem(0); // 애니메이션과 함께 항목 삽입
이러면 추가하는 메서드는 끝났다. 이제 제거하는 동작도 비슷하게 만들어주면 되겠다.
제거하는 동작은 리스트의 인덱스가 필요하기 때문에 인자값으로 index 를 받아주어야 한다. 설명은 귀찮으니 주석으로 대신하겠다
// AnimatedList에서 항목을 제거하는 메서드
void _removeItem(int index) {
// 제거될 항목을 리스트에서 꺼내고 변수에 저장 (애니메이션 빌더에서 사용됨)
final removedItem = _items.removeAt(index);
// AnimatedListState를 통해 애니메이션과 함께 항목 제거
_listKey.currentState!.removeItem(
index, // 제거할 항목의 인덱스
(context, animation) => SizeTransition( // 애니메이션 빌더: 제거 애니메이션 정의
sizeFactor: animation, // 애니메이션 효과로 크기 변화 적용
child: ListTile(title: Text(removedItem)), // 제거될 항목의 위젯
),
);
}
이렇게 하여 메서드는 다 만들었다. 그럼 이제 본 코드에서는
AnimatedList(
key: _listKey,
initialItemCount: _items.length,
key 만들어둔 GlobalKey 를 넣어주고 initialItemCount 에는 가장 먼저 만들어둔 List 를 넣어주면 되겠다.
빌더 함수안에서는 SizeTrasition 을 사용하여 애니메이션을 주었다.
itemBuilder: (context, index, animation) {
return SizeTransition(
sizeFactor: animation,
child: ListTile(
title: Text(_items[index]),
그리고 만들어둔 메서드들은 어떻게 사용하든지 마음대로 하면 될것이다.
ElevatedButton(onPressed: _addItem, child: Text('Add Item')),
이렇게 AnimatedList 에 대해 알아보았다. 막 엄청 어려운 개념을 담은 위젯도 아니고 사용법이 괴랄한것도 아닌데 이거 예제 영상 길이가 젤 괴랄한것 같다. 보통 1분 초중반으로 영상 길이 맞추는게 모토 아니었나 의문이 드는 영상 길이 인것 같다. 암튼 도움이 되었길 바라며 마치겠다.