본문 바로가기
플러터(flutter)

플러터의 AnimatedBuilder를 사용하여 Animation 만들기 - 2

by 기계공학 주인장 2023. 12. 20.
반응형

이전 포스팅에서는 플러터에서 사용되는 애니메이션에서

 

플러터의 명시적(Explict) 애니메이션암시적(Implict) 애니메이션에 대해 알아봤습니다.

 

그리고 간단하게 명시적 애니메이션을 정의하는 방법과 사용하는 방법에 대해 알아봤는데요.

 

 

플러터의 AnimatedBuilder를 사용하여 Animation 만들기 - 1

플러터(Flutter)의 애니메이션은 두 가지 방법이 존재합니다. 명시적(Explict) 애니메이션 암시적(Implict) 애니메이션 둘의 차이점은 다음과 같습니다. 플러터의 명시적(Explict) 애니메이션 플러터에서

android-developer.tistory.com

 

이번에는 다음과 같은 내용을 알아보겠습니다.

 

  1. 명시적 애니메이션에서 AnimatedBuilderbuildertransition으로 구현하는 방법
  2. 암시적 애니메이션 사용 방법

명시적 애니메이션 AnimatedBuilder에서 builder를 transition으로 구현하기

이전 포스팅에서 AnimatedBuilder의 builder 함수를 다음과 같은 방법으로 구현했습니다.

 

@override
  Widget build(BuildContext context) {
    // child: 애니메이션을 재생해도 변화하지 않는 부분(= 기존의 UI 부분)
    return AnimatedBuilder(
      animation: _animationController,
      child: GridView(
        padding: const EdgeInsets.all(16),
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 3 / 2,
          crossAxisSpacing: 20,
          mainAxisSpacing: 20,
        ),
        children: [
          for (final category in availableCategories)
            CategoryGridItem(
              category: category,
              onSelectCategory: () {
                _selectCategory(context, category);
              },
            )
        ],
      ),
      // AnimatedBuilder에 전달되는 함수로, 애니메이션이 변화할 때마다 호출되어 위젯을 다시 빌
      builder: (context, child) => Padding(
          padding: EdgeInsets.only(
            top: 100 - _animationController.value * 100,
          ),
          child: child),
    );
  }

 

애니메이션 호출을 Padding을 사용하여 수동으로 구현했죠.

 

하지만 다음과 같은 Transition들을 사용해도 구현할 수 있습니다.

 

builder: (context, child) => SlideTransition(
        position: Tween(
          begin: const Offset(0, 0.3),
          end: const Offset(0, 0),
        ).animate(CurvedAnimation(
          parent: _animationController,
          curve: Curves.easeInOut,
        )),
        child: child,
      )

 

예로든 transition은 SlideTransition이지만 플러터 공식 문서에서

 

여러 Transition들을 볼 수 있습니다.

 

 

Animate a page route transition

How to animate from one page to another.

docs.flutter.dev

 

전체 코드는 다음과 같습니다.

 

@override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animationController,
      child: GridView(
        padding: const EdgeInsets.all(16),
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 3 / 2,
          crossAxisSpacing: 20,
          mainAxisSpacing: 20,
        ),
        children: [
          for (final category in availableCategories)
            CategoryGridItem(
              category: category,
              onSelectCategory: () {
                _selectCategory(context, category);
              },
            )
        ],
      ),
      builder: (context, child) => SlideTransition(
        position: Tween(
          begin: const Offset(0, 0.3),
          end: const Offset(0, 0),
        ).animate(CurvedAnimation(
          parent: _animationController,
          curve: Curves.easeInOut,
        )),
        child: child,
      ),
    );
  }

 

결과는 플러터의 AnimatedBuilder를 사용하여 Animation 만들기 - 1에서 했던 것과 동일합니다.

 


암시적 애니메이션 사용하기

플러터의 암시적 애니메이션을 사용하여 Icon을 회전시키는 애니메이션을 만들어보겠습니다.

 

먼저 appBar에 다음과 같은 아이콘이 있다고 가정하겠습니다.

 

Scaffold(
  appBar: AppBar(
    title: Text(meal.title),
    actions: [
      IconButton(
        onPressed: () {
          final wasAdded = ref.read(favoriteMealsProvider.notifier).toggleMealFavoriteStatus(meal);
          ScaffoldMessenger.of(context).clearSnackBars();
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(wasAdded ? 'Meal added as a favorite' : 'Meal removed'),
            ),
          );
        },
        // 이 아이콘에 애니메이션 넣을 예정
        icon: Icon(isFavorite ? Icons.star : Icons.star_border),
      )
    ],
  ),
  body: ~~
}

 

appBar의 아이콘의 경우 AnimatedSwitcher를 사용하여 애니메이션을 넣을 수 있습니다.

 

AnimatedSwicher란, 두 위젯 간의 전환을 애니메이션으로 처리할 수 있게 해주는 위젯입니다.

 

그렇기 때문에 해당 아이콘을 클릭하면 다른 아이콘으로 전환되는 것을 AnimatedSwitcher로 구현합니다.

 

Scaffold(
  appBar: AppBar(
    title: Text(meal.title),
    actions: [
      IconButton(
        onPressed: () {
          final wasAdded = ref.read(favoriteMealsProvider.notifier).toggleMealFavoriteStatus(meal);
          ScaffoldMessenger.of(context).clearSnackBars();
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(wasAdded ? 'Meal added as a favorite' : 'Meal removed'),
            ),
          );
        },
        // AnimatedSwitcher는 두 위젯간의 전환을 애니메이션으로 처리해준다.
        icon: AnimatedSwitcher(
          duration: const Duration(milliseconds: 300),
          // 어떤 애니메이션을 적용할지 지정
          // transitionBuilder에서 사용되는 child, animation 인자는 flutter에서 제공된다.
          transitionBuilder: (child, animation) {
            // begin, end를 조절하여 animation의 강도를 조절할 수 있다.
            return RotationTransition(turns: Tween(begin: 0.8, end: 1.0).animate(animation), child: child);
          },
          child: Icon(
            isFavorite ? Icons.star : Icons.star_border,
            key: ValueKey(isFavorite),
          ),
        ),
      )
    ],
  ),
  body: ~~~
}

 

테스트 해보면 다음과 같이 appBar에 있는 아이콘을 클릭하면 회전하는 것을 볼 수 있습니다.

 

 

참고로 RotationTransitionZ축으로만 회전시킬 수 있으니 Y축으로 회전시키고싶다면 다른 방법을 사용해야 합니다.


 

 

플러터에서 Rest API로 Firebase Realtime Database 사용하기 -1

이번에는 플러터에서 Rest API로 Firebase의 Realtime Database를 사용하는 방법에 대해 알아보겠습니다. 굳이 Firebase의 Realtime Database을 사용하는 이유는 Rest API를 지원하기 때문입니다. 아래의 공식 문서

android-developer.tistory.com

 

반응형


"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."


댓글