이전 포스팅에서는 플러터에서 사용되는 애니메이션에서
플러터의 명시적(Explict) 애니메이션과 암시적(Implict) 애니메이션에 대해 알아봤습니다.
그리고 간단하게 명시적 애니메이션을 정의하는 방법과 사용하는 방법에 대해 알아봤는데요.
플러터의 AnimatedBuilder를 사용하여 Animation 만들기 - 1
플러터(Flutter)의 애니메이션은 두 가지 방법이 존재합니다. 명시적(Explict) 애니메이션 암시적(Implict) 애니메이션 둘의 차이점은 다음과 같습니다. 플러터의 명시적(Explict) 애니메이션 플러터에서
android-developer.tistory.com
이번에는 다음과 같은 내용을 알아보겠습니다.
- 명시적 애니메이션에서 AnimatedBuilder의 builder를 transition으로 구현하는 방법
- 암시적 애니메이션 사용 방법
명시적 애니메이션 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에 있는 아이콘을 클릭하면 회전하는 것을 볼 수 있습니다.

참고로 RotationTransition은 Z축으로만 회전시킬 수 있으니 Y축으로 회전시키고싶다면 다른 방법을 사용해야 합니다.
플러터에서 Rest API로 Firebase Realtime Database 사용하기 -1
이번에는 플러터에서 Rest API로 Firebase의 Realtime Database를 사용하는 방법에 대해 알아보겠습니다. 굳이 Firebase의 Realtime Database을 사용하는 이유는 Rest API를 지원하기 때문입니다. 아래의 공식 문서
android-developer.tistory.com
'플러터(flutter)' 카테고리의 다른 글
| 플러터에서 Firebase SDK 사용하기 (SDK 설치하기) (0) | 2024.01.04 | 
|---|---|
| 플러터에서 Rest API로 Firebase Realtime Database 사용하기 (1) | 2023.12.23 | 
| 플러터의 AnimatedBuilder를 사용하여 Animation 만들기 - 1 (1) | 2023.12.11 | 
| 플러터의 Riverpod 사용 방법 기초부터 자세히 설명 - 2 (0) | 2023.12.07 | 
| 플러터의 Riverpod 사용 방법 기초부터 자세히 설명 - 1 (4) | 2023.12.06 | 
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
 
										
									 
										
									 
										
									 
										
									 
댓글