seong

Flutter - flutter_staggered_animations 애니메이션 적용기 본문

Flutter/Flutter

Flutter - flutter_staggered_animations 애니메이션 적용기

hyeonseong 2024. 11. 10. 16:36

https://pub.dev/packages/flutter_staggered_animations

 

flutter_staggered_animations | Flutter package

Easily add staggered animations to your ListView, GridView, Column and Row children as shown in Material Design guidelines

pub.dev

적용 할 애니메이션

최초 빌드 시 ListView, 버튼 클릭 할 때 마다  GridView <-> ListView 각 애니메이션이 바뀌게.

적용 하면서 알게 된 사항 

- 위젯이 빌드 시 처음 렌더링 될 때만 애니메이션이 적용 된다, 즉 + 버튼을 눌러 ListView와 GridView를 전환할 때 애니메이션이 적용 되지 않는데, Flutter의 위젯 렌더링 방식 때문이다, 그래서 setState()를 호출 해도 애니메이션이 각각 적용이 되지 않는다

그래서 해결 방법으로 각 위젯에 UniqueKey를 적어주면 새로 빌드 하기 때문에 애니메이션이 재시작 된다.

적용 화면

 

 


  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 1280,
      child: Column(
        children: [
          // +ALL 버튼을 보여줌
          Align(
            alignment: Alignment.topRight,
            child: plusButton(() {
              if (mounted) {
                setState(() {
                  isGridView = !isGridView; // 버튼 클릭 시 GridView 상태로 변경
                });
              }
            }),
          ),
          const SizedBox(height: 8),
          // 상태에 따라 ListView 또는 GridView로 전환
          isGridView
              ? buildGridView(key: UniqueKey())
              : buildListView(key: UniqueKey()),
        ],
      ),
    );
  }

 

GridView 위젯

  Widget buildGridView({Key? key}) {
    int columnCount = 4;
    return SizedBox(
      height: 2000,
      child: AnimationLimiter(
        key: key,
        child: GridView.builder(
          padding: const EdgeInsets.symmetric(horizontal: 34),
          itemCount: widget.cardItem.length,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: columnCount,
            crossAxisSpacing: 0,
            mainAxisSpacing: 0,
            childAspectRatio: 0.7, // 이미지 비율에 맞춰 설정
          ),
          itemBuilder: (context, index) {
            return AnimationConfiguration.staggeredGrid(
              position: index,
              duration: const Duration(milliseconds: 375),
              columnCount: columnCount,
              child: ScaleAnimation(
                child: FadeInAnimation(
                  child: buildImageCard(index), // 원하는 위젯
                ),
              ),
            );
          },
        ),
      ),
    );
  }

 

ListView 위젯

Widget buildListView({Key? key}) {
  return SizedBox(
    width: totalWidth * 4,
    height: 476,
    child: AnimationLimiter(
      key: key,
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: widget.cardItem.length,
        itemBuilder: (BuildContext context, int index) {
          return AnimationConfiguration.staggeredList(
            position: index,
            duration: const Duration(milliseconds: 375),
            child: SlideAnimation(
                verticalOffset: 50,
                child: FadeInAnimation(child: buildImageCard(index))),
          );
        },
      ),
    ),
  );
}