Containerクラスは、幅、高さ、背景色、パディング、境界線などの特定のプロパティを持つウィジェットを作成するための便利な方法を提供します。
単純なアニメーションでは、多くの場合、これらのプロパティを時間の経過とともに変更する必要があります。
たとえば、背景色を灰色から緑色にアニメーション化して、アイテムがユーザーによって選択されたことを示すことができます。
これらのプロパティをアニメーション化するために、FlutterにはAnimatedContainerウィジェットが用意されています。
コンテナウィジェットと同様に、AnimatedContainerを使用すると、幅、高さ、背景色などを定義できます。
ただし、AnimatedContainerが新しいプロパティで再構築されると、古い値と新しい値の間で自動的にアニメーション化されます。 Flutterでは、これらのタイプのアニメーションは「暗黙のアニメーション」と呼ばれます。
このページでは、AnimatedContainerを使用して、ユーザーがボタンをタップしたときに、サイズ、背景色、および境界線の半径をアニメーション化する方法について次の手順で説明していきます。
- デフォルトのプロパティの値でStatefulWidgetを生成する。
- (1)で用いたプロパティを使ってAnimatedContainerウィジェットを生成する
- 新しいプロパティの値を用いてアニメーションをスタートさせる。
1. Create a StatefulWidget with default properties
まず、StatefulWidgetクラスとStateクラスを作成します。
カスタムStateクラスを使用して、時間の経過とともに変化するプロパティを定義します。
この例では、幅、高さ、色、境界線の半径が含まれています。 各プロパティのデフォルト値を定義することもできます。
これらのプロパティはカスタムStateクラスに属しているため、ユーザーがボタンをタップしたときに更新できます。
class AnimatedContainerApp extends StatefulWidget {
@override
_AnimatedContainerAppState createState() => _AnimatedContainerAppState();
}
class _AnimatedContainerAppState extends State<AnimatedContainerApp> {
// Define the various properties with default values. Update these properties
// when the user taps a FloatingActionButton.
double _width = 50;
double _height = 50;
Color _color = Colors.green;
BorderRadiusGeometry _borderRadius = BorderRadius.circular(8);
@override
Widget build(BuildContext context) {
// Fill this out in the next steps.
}
}
2. Build an AnimatedContainer
using the properties
次に、前の手順で定義したプロパティを使用してAnimatedContainerをビルドします。
さらに、アニメーションを実行する時間を定義するdurationを指定します。
AnimatedContainer(
// ↓Stateクラスで定義したプロパティを使います。
width: _width,
height: _height,
decoration: BoxDecoration(
color: _color,
borderRadius: _borderRadius,
),
// ↓アニメーションの開始→終了の時間を指定します。
duration: Duration(seconds: 1),
// ↓アニメーションの進行の仕方を定義します。
curve: Curves.fastOutSlowIn,
);
最後に、AnimatedContainerを新しいプロパティで再構築してアニメーションを開始します。 再構築をトリガーする方法は? setState()メソッドを使用します。
setState()メソッド実行→state(状態)が変更→リビルドでアニメーション開始。
アプリにボタンを追加します。 ユーザーがボタンをタップすると、setState()の呼び出し内で、プロパティが新しい幅、高さ、背景色、境界線の半径で更新されます。
(このサンプルでは毎回ランダム値を生成しているが、)実際のアプリは通常、固定値の間で遷移します(たとえば、灰色から緑色の背景に)。
このアプリでは、ユーザーがボタンをタップするたびに新しい値を生成します。
FloatingActionButton(
child: Icon(Icons.play_arrow),
// When the user taps the button
onPressed: () {
// ↓新しい値でウィジェットをリビルドする
//(アニメーション開始する)ためにsetStateを使います。
setState(() {
// ランダム値を生成するためRndomeインスタンスを生成します。
final random = Random();
// 幅と高さのランダム値を生成します。
_width = random.nextInt(300).toDouble();
_height = random.nextInt(300).toDouble();
// ランダムな色を取得します。
_color = Color.fromRGBO(
random.nextInt(256),
random.nextInt(256),
random.nextInt(256),
1,
);
// ランダムな角の丸み(borderRadius)を生成します。
_borderRadius =
BorderRadius.circular(random.nextInt(100).toDouble());
});
},
);
まとめのサンプル
import 'dart:math'; import 'package:flutter/material.dart'; void main() => runApp(AnimatedContainerApp()); class AnimatedContainerApp extends StatefulWidget { @override _AnimatedContainerAppState createState() => _AnimatedContainerAppState(); } class _AnimatedContainerAppState extends State<AnimatedContainerApp> { // Define the various properties with default values. Update these properties // when the user taps a FloatingActionButton. double _width = 50; double _height = 50; Color _color = Colors.green; BorderRadiusGeometry _borderRadius = BorderRadius.circular(8); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('AnimatedContainer Demo'), ), body: Center( child: AnimatedContainer( // Use the properties stored in the State class. width: _width, height: _height, decoration: BoxDecoration( color: _color, borderRadius: _borderRadius, ), // Define how long the animation should take. duration: Duration(seconds: 1), // Provide an optional curve to make the animation feel smoother. curve: Curves.fastOutSlowIn, ), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.play_arrow), // When the user taps the button onPressed: () { // Use setState to rebuild the widget with new values. setState(() { // Create a random number generator. final random = Random(); // Generate a random width and height. _width = random.nextInt(300).toDouble(); _height = random.nextInt(300).toDouble(); // Generate a random color. _color = Color.fromRGBO( random.nextInt(256), random.nextInt(256), random.nextInt(256), 1, ); // Generate a random border radius. _borderRadius = BorderRadius.circular(random.nextInt(100).toDouble()); }); }, ), ), ); } }
参考
https://flutter.dev/docs/cookbook/animation/animated-container