0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】アニメーションAnimationControllerの使い方

Last updated at Posted at 2022-12-19

※本記事は下記のZenn本にまとめました。

はじめに

FlutterのAnimationControllerを用いて、アニメーションを実現する方法をまとめてみます。
今回は例を使ってAnimationControllerの使い方をまとめます。
※今記事のサンプルソースはGithubにアップロードしています。

AnimationController

コンストラクター

変数 デフォルト値 説明
value double null アニメーションコントローラーの初期値
duration Duration null アニメーションの長さ
reverseDuration Duration null アニメーション逆再生時間
lowerBound double 0.0 アニメーション下限
upperBound double 1.0 アニメーション上限
animationBehavior AnimationBehavior normal アニメーション動作
vsync TickerProvider required Tickerプロバイダー

初期値valueと長さduration

  1. valueはコントローラーの初期値であり、下記の例では初期値は0.4から1.0まで変化する
  2. durationはアニメーションの長さを表す、下記の例は500msと2000msで見比べて貰えば、一目瞭然

/lib/value_duration/font_anim.dart

late AnimationController _ctrl;

  final Duration animDuration = const Duration(milliseconds: 500);

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
      value: 0.4,
      vsync: this,
      duration: animDuration,
    );
  }

  @override
  void dispose() {
    _ctrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _startAnim,
      child: AnimatedBuilder(
        animation: _ctrl,
        builder: (_, __) {
          return Text(
            "Animation",
            style: TextStyle(
              color: Colors.blue,
              fontSize: fontSize,
            ),
          );
        },
      ),
    );
  }

  double get fontSize => 60 * _ctrl.value;

  void _startAnim() {
    _ctrl.reset();
    _ctrl.forward();
  }

2000ms 500ms

reverseDurationは逆再生時間を表す
ソースコードanimation_controller.dartの588行目あたり下記の記述がある
つまりreverseDurationを定義しないと逆再生できないとのこと

     final Duration directionDuration =
        (_direction == _AnimationDirection.reverse && reverseDuration != null)
        ? reverseDuration!
        : this.duration!;

下記の例ではreverseDurationを定義した上で_ctrl.reverse();を呼び出す

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
      value: 1,
      vsync: this,
      //duration: animDuration,
      lowerBound: 0.4,
      reverseDuration: animDuration,
    );
  }
...
  void _startAnim() {
    _ctrl.reverse();
  }

lowerBoundとupperBound

lowerBoundとupperBoundを定義しなければ、コントローラーの値は0.0~1.0まで変化するが、
下記の例のように定義していれば、上下値は18~60となり、コントローラーの値は32~80まで変化する。
では、fontSizeは_ctrl.valueに設定して貰えば、fontSizeは18~60まで変化することとなる

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
      //value: 0.4,
      vsync: this,
      duration: animDuration,
      lowerBound: 18,
      upperBound: 60,
      //reverseDuration: animDuration,
    );
  }
  // フォントサイズ
  double get fontSize => _ctrl.value;

animationBehaviorアニメーション動作

  /// The behavior of the controller when [AccessibilityFeatures.disableAnimations]
  /// is true.
  ///
  /// Defaults to [AnimationBehavior.normal] for the [new AnimationController]
  /// constructor, and [AnimationBehavior.preserve] for the
  /// [new AnimationController.unbounded] constructor.
  final AnimationBehavior animationBehavior;

列挙型の変数です。デフォルトはAnimationBehavior.normal
AnimationController.unboundedコンストラクターの場合はthis.animationBehavior = AnimationBehavior.preserve,となっている

enum AnimationBehavior {
  // [AccessibilityFeatures.disableAnimations]がtureの場合、duration時間を短縮する
  normal,
  // [AccessibilityFeatures.disableAnimations]がtureの場合、その動作を保持する
  preserve,
}
  AnimationController.unbounded({
    double value = 0.0,
    this.duration,
    this.reverseDuration,
    this.debugLabel,
    required TickerProvider vsync,
    this.animationBehavior = AnimationBehavior.preserve,
  }) : assert(value != null),
       assert(vsync != null),
       lowerBound = double.negativeInfinity,
       upperBound = double.infinity,
       _direction = _AnimationDirection.forward {
    _ticker = vsync.createTicker(_tick);
    _internalSetValue(value);
  }

VS CODEのデバッグでMediaQuery.of(context)で変数監視するとその値確認できる

AnimationControllerの関数

  1. forward
    アニメーションの開始メソッドであり、アニメーションコントローラーデフォルト値は0.0~1.0まで変化する。lowerBoundとupperBound設定すれば、値は[lowerBound〜upperBound]変化する
  2. reverse
    アニメーションの逆生成メソッドであり、アニメーションコントローラーデフォルト値は1~0.0まで変化する。lowerBoundとupperBound設定すれば、値は[upperBound〜lowerBound]変化する
  3. repeat
    パラメーター:
    1. min: アニメーション値の下限(デフォルトはアニメーションコントローラーの下限)
    2. max: アニメーション値の上限(デフォルトはアニメーションコントローラーの上限)
    3. reverse: アニメーション逆生成(デフォルトはfalse)
    4. duration: アニメーションの長さ(デフォルトはアニメーションコントローラーの長さ)
    
    reverseがfalseの場合、アニメーション値は[最小値〜最大値、最小値〜最大値...]の繰り返し
    reverseがtrueの場合は、アニメーション値は[最小値〜最大値、最大値〜最小値、最大値〜最小値...]の繰り返し
    repeat
    false true
  4. reset
    resetはアニメーション値を下限値にリセットする
      void reset() {
        value = lowerBound;
      }
    
  5. stop
    動画を停止する
  6. fling
    言葉の通りです。アニメーションの値を急に増える感じです。
    下記の例で一目瞭然です。

    パラメーター
    属性 デフォルト値 説明
    velocity double 1.0 速度
    springDescription SpringDescription null スプリング パラメータの構成
    animationBehavior AnimationBehavior null アニメーション動作
     const SpringDescription({
        required this.mass, // 質量
        required this.stiffness,// 剛性
        required this.damping,// ダンピング
     });
    
     SpringDescription.withDampingRatio({
        required this.mass,
        required this.stiffness,
        double ratio = 1.0,
     }) : damping = ratio * 2.0 * math.sqrt(mass * stiffness);
    
    デフォルトは
    final SpringDescription _kFlingSpringDescription = SpringDescription.withDampingRatio(
      mass: 1.0,
      stiffness: 500.0,
      ratio: 1.0,
    );
    
    ダンピング大きいほどかかった時間が長い
    下記の例で動作を確認しましょう。
    /lib/function/fling/line_anim.dart
    void _startAnim() async {
        _ctrl.reset();
        _ctrl.fling(
          velocity: 10,
          springDescription: SpringDescription.withDampingRatio(
            mass: 1.0,
            stiffness: 500.0,
            ratio: 5.0,
          ),
       );
    }
    
  7. dispose
    _ticker オブジェクトを破棄する
  8. animateTo
  9. animateBack
  10. animateWith

AnimationControllerの状態監視

enum AnimationStatus {
  /// The animation is stopped at the beginning.
  dismissed,

  /// The animation is running from beginning to end.
  forward,

  /// The animation is running backwards, from end to beginning.
  reverse,

  /// The animation is stopped at the end.
  completed,
}

addStatusListenerで状態の変化を監視できる

_ctrl = AnimationController(
    vsync: this,
    duration: animDuration,
  )..addStatusListener(_listenStatus);
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?