【Flutter】そのまま使えるアニメーションWidget(AnimatedWidget編)

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

https://zenn.dev/cxj/books/07def04506182d

# AnimatedWidget家族
**AnimatedWidget** は抽象です。その親子関係は下記です。その共通点としては**animation** が必要です。（`required Listenable animation,`）代表的なAnimatedWidgetは**AnimatedBuilder** です。
```dart
AnimatedWidget [abstract]
|---AnimatedModalBarrier
|---SlideTransition
|---ScaleTransition
|---RotationTransition
|---SizeTransition
|---PositionedTransition
|---RelativePositionedTransition
|---DecoratedBoxTransition
|---AlignTransition
|---DefaultTextStyleTransition
|---AnimatedBuilder
```

## AnimatedBuilderのコンストラクター
animationが必須です。
```dart
  /// Creates an animated builder.
  ///
  /// The [animation] and [builder] arguments must not be null.
  const AnimatedBuilder({
    Key? key,
    required Listenable animation,
    required this.builder,
    this.child,
  }) : assert(animation != null),
       assert(builder != null),
       super(key: key, listenable: animation);
```
# AnimatedWidgetの使用例

## SizeTransition
```dart
  const SizeTransition({
    Key? key,
    this.axis = Axis.vertical,
    required Animation<double> sizeFactor,
    this.axisAlignment = 0.0,
    this.child,
  }) : assert(axis != null),
       assert(sizeFactor != null),
       assert(axisAlignment != null),
       super(key: key, listenable: sizeFactor);
```
**SizeTransition** を使用して、部品サイズ変化のアニメーションを実行させることができます。 
タイプ `Animation<double>` のアニメーターを渡す必要があります。

[size_transition_page.dart](https://github.com/ling350181/flutter_ui/blob/main/lib/animation/animated_widget/size_transition_page.dart)

<img src=https://storage.googleapis.com/zenn-user-upload/46387ac995d3-20230305.gif width=300>



## ScaleTransition
```dart
  const ScaleTransition({
    Key? key,
    required Animation<double> scale,
    this.alignment = Alignment.center,
    this.filterQuality,
    this.child,
  }) : assert(scale != null),
       super(key: key, listenable: scale);
```
**ScaleTransition** を使用して、スケーリング アニメーションを実行させることができます。 
タイプ `Animation<double>` のアニメーターを渡す必要があります、 さらに、スケールの中心はデフォルトで`Alignment.center`設定されます。

[scale_transition_page.dart](https://github.com/ling350181/flutter_ui/blob/main/lib/animation/animated_widget/scale_transition_page.dart)

<img src=https://storage.googleapis.com/zenn-user-upload/26c90753240a-20230305.gif width=300>

## RotationTransition
```dart
  const RotationTransition({
    Key? key,
    required Animation<double> turns,
    this.alignment = Alignment.center,
    this.filterQuality,
    this.child,
  }) : assert(turns != null),
       super(key: key, listenable: turns);
```

**RotationTransition** を使用して、コンポーネントを回転するアニメーションさせることができます。タイプ `Animation<double>` 型のアニメーターを渡す必要があります。さらに、回転の中心はデフォルトで`Alignment.center`設定されます。

[rotation_transition_page.dart](https://github.com/ling350181/flutter_ui/blob/main/lib/animation/animated_widget/rotation_transition_page.dart)

<img src=https://storage.googleapis.com/zenn-user-upload/ef5e80b70422-20230305.gif width=300>

## SlideTransition
```dart
  const SlideTransition({
    Key? key,
    required Animation<Offset> position,
    this.transformHitTests = true,
    this.textDirection,
    this.child,
  }) : assert(position != null),
       super(key: key, listenable: position);
```

**SlideTransition** を使用して、コンポーネントが親領域でスライドアニメーションを実行できす。タイプ `Animation<Offset>` のアニメーターを渡す必要があります。さらに、bool値 `transformHitTests` で移動されたコンポーネントの`HitTests`が影響されるがどうかを設定します。デフォルトは `true` です。`textDirection`は移動方向です。
```dart
enum TextDirection {
  rtl,
  ltr,
}
```

[slide_transition_page.dart](https://github.com/ling350181/flutter_ui/blob/main/lib/animation/animated_widget/slide_transition_page.dart)

<img src=https://storage.googleapis.com/zenn-user-upload/026c3b56fb2b-20230305.gif width=300>

## AlignTransition
```dart
  const AlignTransition({
    Key? key,
    required Animation<AlignmentGeometry> alignment,
    required this.child,
    this.widthFactor,
    this.heightFactor,
  }) : assert(alignment != null),
       assert(child != null),
       super(key: key, listenable: alignment);
```

**lignTransition** は、子Widgetが親の領域内での整列移動アニメーションです。`AlignmentGeometry`型のアニメーターを渡す必要があります。さらに、`widthFactor`と`heightFactor`はそれぞれ幅と高さ係数であり、Align Widgetと同じ役割を果たします。childは移動させたい`Widget`です。

[align_transition_page.dart](https://github.com/ling350181/flutter_ui/blob/main/lib/animation/animated_widget/align_transition_page.dart)

<img src=https://storage.googleapis.com/zenn-user-upload/f72510813050-20230309.gif width=300>

## DecoratedBoxTransition
```dart
  const DecoratedBoxTransition({
    Key? key,
    required this.decoration,
    this.position = DecorationPosition.background,
    required this.child,
  }) : assert(decoration != null),
       assert(child != null),
       super(key: key, listenable: decoration);
```

**DecoratedBoxTransition** は、Widgetに装飾アニメーションを適用できます。`Decoration` 型のアニメーターを渡す必要があります。さらに、`position`パラメーターは前景装飾か背景装飾かを制御します。childは移動させたい`Widget`です。

```dart
enum DecorationPosition {
  /// Paint the box decoration behind the children.
  background,
  /// Paint the box decoration in front of the children.
  foreground,
}
```

[decorated_box_transition_page.dart](https://github.com/ling350181/flutter_ui/blob/main/lib/animation/animated_widget/decorated_box_transition_page.dart)

<img src=https://storage.googleapis.com/zenn-user-upload/26b5f1f3edf2-20230309.gif width=300>