AnimationBuilder로 만드는 펑펑 튀는 Widget

12303 단어 FlutterWebFlutter

자연스럽게 유저의 주의를 끌고 싶을 때, 뛰어넘어 어필하는 것이 유효합니다
MacOS의 Dock에서도 백그라운드에서 업데이트 된 앱이 흠뻑 튀어 나올 수 있습니다.
많이 사용하면 눈에 띄지만 포인트로 사용하면 유효할까 생각합니다

이번에는 Flutter의 AnimationBuilder를 사용하여 임의의 Widget을 튕겨내는 컨테이너 클래스를 작성해 보았습니다.

Flutter의 애니메이션 유형



공식 문서 에서, 차트 첨부로 해설하고 있습니다. 친절합니다.

이번 경우에는
  • 그림을 그리는 애니메이션이 하고 싶어? → 아니오
  • 텍스트 애니메이션을 원하십니까? → 아니오
  • 애니메이션이 항상 전면에 있을 수 있습니까? → 예
  • 애니메이션 값에 불연속성이 없는가? → 예
  • 간단하게, 무한하게 반복할 필요는 없나? → 예
  • 하나의 아이 Widget만을 움직이고 싶습니까? → 예

  • 라고 말하면 TweenAnimationBuilder를 사용하기로 결정했습니다.

    단순히 크게 or 작게 하거나, 한 방향으로 움직이는 것 같은 애니메이션이라면, AnimatedContainer 쪽이 간편할 것 같습니다. 뛰어오르는 동작의 경우는, 날아, 떨어진다, 라고 하는 2 액션이 필요하므로 AnimatedContainer에서는 구현이 어려울 것 같았습니다

    펑펑 뛰어 넘는 Container 구현



    라고 말하는 것으로 구현해 본 것이 이쪽입니다

    소스 코드



    bounce_container.dart
    import 'package:flutter/cupertino.dart';
    
    // ========== アニメーション定義 ========== //
    // 飛び上がりアニメーション
    final _bounceUp = TweenSequenceItem<double>(
      weight: 1,
      tween: Tween(
        begin: 0.0, end: -30.0
      ).chain(CurveTween(curve: Curves.easeOutCubic))
    );
    // 飛び下がりアニメーション
    final _bounceDown = TweenSequenceItem<double>(
      weight: 1,
      tween: Tween(
        begin: -30.0, end: 0.0
      ).chain(CurveTween(curve: Curves.easeInCubic))
    );
    // 有限回数繰り返すために、TweenSequenceでその分定義する
    final _sequence = TweenSequence<double>(
        <TweenSequenceItem<double>>[
          _bounceUp,
          _bounceDown,
          _bounceUp,
          _bounceDown,
          _bounceUp,
          _bounceDown
        ]
    );
    
    // ========== Widget定義 ========== //
    class BounceContainer extends StatefulWidget {
      final Widget child;
      final state = _BounceContainerState();
    
      BounceContainer({required this.child});
    
      @override
      State<StatefulWidget> createState() => state;
    
      // 外部からアニメーションをトリガーするための公開メソッド
      void bounce() {
        state.animate();
      }
    }
    
    // Stateful WidgetかつSingleTickerProviderStateMixinが必要
    class _BounceContainerState extends State<BounceContainer> with SingleTickerProviderStateMixin {
      late AnimationController animController;
      late Animation<double> animTween;
    
      @override
      void initState() {
        super.initState();
    
        animController = AnimationController(
          vsync: this,
          duration: Duration(milliseconds: 2000),
        );
        animTween = _sequence.animate(animController);
      }
    
      @override
      void dispose () {
        animController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
            animation: animController,
            builder: (context, child) {
              return Transform.translate(
                  offset: Offset(0, animTween.value),
                  child: widget.child);
            }
        );
      }
    
      void animate() {
        animController.reset(); // resetしないと2回目以降に動かない
        animController.forward();
      }
    }
    

    사용하는 쪽 소스 코드



    FloatingActionButton을 누르면 흠뻑 빠집니다.

    main.dart
    class MyHomePage extends StatelessWidget {
      final bounceIcon = BounceContainer(
          child: Icon(Icons.tag_faces)
      );
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            toolbarHeight: 0,
          ),
          body: Center(
            child: bounceIcon,
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              bounceIcon.bounce();
            },
            child: Icon(Icons.repeat),
          ),
        );
      }
    }
    

    애니메이션 유형으로 대공 시간 조정



    TweenSequence의 Curves를 사용하면 펑펑 상태를 조정할 수 있습니다.
    Curves 애니메이션 패턴은 공식적으로
  • easeIn/Out(왼쪽)
  • easeIn/OutCubic(중앙)
  • easeIn/OutCirc (오른쪽)

  • 좋은 웹페이지 즐겨찾기