<

千鳥アニメーション

千鳥アニメーションは、視覚的な変化という単純なコンセプトです。 一度にではなく、一連の操作として実行されます。 アニメーションは純粋にシーケンシャルであり、その後に 1 つの変更が発生する場合があります。 あるいは、部分的または完全に重複する可能性があります。それはまたかもしれません 変化が起こらないギャップがあります。

このガイドでは、Flutter で千鳥アニメーションを構築する方法を説明します。

次のビデオは、によって実行されるアニメーションを示しています。 Basic_staggered_animation:

ビデオでは、単一のウィジェットの次のアニメーションが表示されます。 これは、わずかに丸い角を持つ、縁取りされた青い正方形として始まります。 四角形は次の順序で変化します。

  1. フェードイン
  2. 広がる
  3. 上に移動すると背が高くなります
  4. 縁取りされた円に変形します
  5. オレンジ色に色が変わります

順方向に実行した後、アニメーションは逆方向に実行されます。

千鳥アニメーションの基本構造

次の図は、Intervalで使用されるBasic_staggered_animation例。 次のような特徴に気づくかもしれません。

  • 不透明度はタイムラインの最初の 10% で変化します。
  • 不透明度の変化の間にはわずかな隙間が生じますが、 そして幅の変化。
  • タイムラインの最後の 25% では何もアニメーションしません。
  • パディングを増やすと、ウィジェットが上に盛り上がって見えるようになります。
  • 境界線の半径を 0.5 に増やすと、 角の丸い正方形を円に変換します。
  • パディングと高さの変更は、 まったく同じ間隔ですが、そうする必要はありません。

Diagram showing the interval specified for each motion

アニメーションを設定するには:

  • を作成しますAnimationControllerすべてを管理するのは、Animations
  • を作成しますTweenアニメーション化されるプロパティごとに。
    • Tween値の範囲を定義します。
    • Tweenanimateメソッドには、parentコントローラーを生成し、Animationその物件のために。
  • で間隔を指定します。Animationcurve財産。

制御アニメーションの値が変化すると、 新しいアニメーションの値が変化し、UI の更新がトリガーされます。

次のコードは、width財産。 それは、CurvedAnimation、 緩和カーブを指定します。見るCurvesために その他の利用可能な事前定義されたアニメーション カーブ。

width = Tween<double>(
  begin: 50.0,
  end: 150.0,
).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(
      0.125, 0.250,
      curve: Curves.ease,
    ),
  ),
),

beginend値は倍精度である必要はありません。 次のコードは、borderRadius財産 (正方形の角の丸みを制御します)、 を使用してBorderRadius.circular()

borderRadius = BorderRadiusTween(
  begin: BorderRadius.circular(4),
  end: BorderRadius.circular(75),
).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(
      0.375, 0.500,
      curve: Curves.ease,
    ),
  ),
),

完全な千鳥アニメーション

すべてのインタラクティブなウィジェットと同様に、完全なアニメーションは次の構成になっています。 ウィジェットのペア: ステートレス ウィジェットとステートフル ウィジェット。

ステートレス ウィジェットは、Tweenさん、 を定義しますAnimationオブジェクトを提供し、build()関数 ウィジェット ツリーのアニメーション部分の構築を担当します。

ステートフル ウィジェットはコントローラーを作成し、アニメーションを再生し、 そして、ウィジェット ツリーの非アニメーション部分を構築します。 画面内のどこかでタップが検出されるとアニメーションが始まります。

Basic_staggered_animation の main.dart の完全なコード

ステートレス ウィジェット: StaggerAnimation

ステートレスウィジェットでは、StaggerAnimation、 のbuild()関数はインスタンスを作成しますAnimatedBuilder- 構築用の汎用ウィジェット アニメーション。のAnimatedBuilderウィジェットを構築し、それを使用して設定します。Tweens' 現在の値。 この例では、という名前の関数を作成します。_buildAnimation()(実行するのは 実際の UI 更新)、それをそのbuilder財産。 AnimatedBuilder はアニメーション コントローラーからの通知をリッスンし、 値の変化に応じてウィジェット ツリーにダーティのマークを付けます。 アニメーションのティックごとに値が更新されます。 その結果、_buildAnimation()

class StaggerAnimation extends StatelessWidget {
  StaggerAnimation({ Key key, this.controller }) :

    // Each animation defined here transforms its value during the subset
    // of the controller's duration defined by the animation's interval.
    // For example the opacity animation transforms its value during
    // the first 10% of the controller's duration.

    opacity = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(
        parent: controller,
        curve: Interval(
          0.0, 0.100,
          curve: Curves.ease,
        ),
      ),
    ),

    // ... Other tween definitions ...

    super(key: key);

  final AnimationController controller;
  final Animation<double> opacity;
  final Animation<double> width;
  final Animation<double> height;
  final Animation<EdgeInsets> padding;
  final Animation<BorderRadius> borderRadius;
  final Animation<Color> color;

  // This function is called each time the controller "ticks" a new frame.
  // When it runs, all of the animation's values will have been
  // updated to reflect the controller's current value.
  Widget _buildAnimation(BuildContext context, Widget child) {
    return Container(
      padding: padding.value,
      alignment: Alignment.bottomCenter,
      child: Opacity(
        opacity: opacity.value,
        child: Container(
          width: width.value,
          height: height.value,
          decoration: BoxDecoration(
            color: color.value,
            border: Border.all(
              color: Colors.indigo[300],
              width: 3.0,
            ),
            borderRadius: borderRadius.value,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      builder: _buildAnimation,
      animation: controller,
    );
  }
}

ステートフル ウィジェット: StaggerDemo

ステートフルなウィジェット、StaggerDemo、を作成します。AnimationController(すべてを支配する者)、2000 ミリ秒の期間を指定します。遊びます アニメーションを作成し、ウィジェット ツリーの非アニメーション部分を構築します。 画面内でタップが検出されるとアニメーションが始まります。 アニメーションは前方に実行され、次に後方に実行されます。

class StaggerDemo extends StatefulWidget {
  @override
  _StaggerDemoState createState() => _StaggerDemoState();
}

class _StaggerDemoState extends State<StaggerDemo> with TickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      duration: const Duration(milliseconds: 2000),
      vsync: this
    );
  }

  // ...Boilerplate...

  Future<void> _playAnimation() async {
    try {
      await _controller.forward().orCancel;
      await _controller.reverse().orCancel;
    } on TickerCanceled {
      // the animation got canceled, probably because it was disposed of
    }
  }

  @override
  Widget build(BuildContext context) {
    timeDilation = 10.0; // 1.0 is normal animation speed.
    return Scaffold(
      appBar: AppBar(
        title: const Text('Staggered Animation'),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          _playAnimation();
        },
        child: Center(
          child: Container(
            width: 300.0,
            height: 300.0,
            decoration: BoxDecoration(
              color: Colors.black.withOpacity(0.1),
              border: Border.all(
                color:  Colors.black.withOpacity(0.5),
              ),
            ),
            child: StaggerAnimation(
              controller: _controller.view
            ),
          ),
        ),
      ),
    );
  }
}