Flutterの基本的なアニメーション
Flutterには、アプリのアニメーション効果を作成するための膨大な量のすばらしいパッケージがありますが、より微調整されたアニメーションを手動で作成するための組み込みのメソッドもあります。
前提条件
クロススクリーンアニメーションでは、簡単にするために、基本的なルートを作成する方法をすでに知っていると想定します。 まだ慣れていない場合は、ドキュメントをここで確認できます。
線形アニメーション
私たちのアニメーションの主な3つの部分は ticker
私たちの時間を制御するために、 controller
期間などのパラメータを登録してから、変更する値を登録します。 ウィジェットがレンダリングされる前に、 initState
、コントローラーをパラメーターに設定し、方向を設定し、リスナーを追加して、変更のたびにウィジェットの状態をリセットできます。
デフォルトでは、コントローラーは、期間に設定した時間内に0から1に変更を移動します。 controller.value
これが起こるのを見るために私たちのリスナーで。 デフォルトの開始値と終了値を変更するには、 upperBound
また lowerBound
プロパティ。
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
AnimationController controller;
void initState() {
super.initState();
controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this); // Links this controller to this widget so it won't run if the parent widget isn't rendered, to save on resources.
controller.forward();
controller.addListener(() => setState(() {}));
}
}
アニメーションを使用するには、不透明度など、必要なものを次のように設定する必要があります。 controller.value
.
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Opacity(
opacity: controller.value,
child: Container(width: 50, height: 50, color: Colors.red),
),
),
);
}
湾曲したアニメーション
退屈な線形アニメーションの代わりに、さまざまな曲線のバリエーションを使用して、コントローラーの変更方法を正確に制御できます。 これを行うには、 CurvedAnimation
元のコントローラーの上に一種のラッパーを作成します。 このラッパーは、その親、コントローラー、および適用するカーブを取得します。 曲線アニメーションを使用する場合、0と1以外に下限と上限を設定することはできないため、適用すると、その値を乗算するだけで済みます。 docsには非常に広範なオプションのリストがあります。
上の別の便利な方法 controller
は addStatusListener
、これにより、そのライフサイクルを活用できるようになります。 コントローラーは、値が上限または下限に達するたびに、完了または却下されたイベントをトリガーします。 これを使用できます forward
と reverse
アニメーションを無限にループするメソッド。
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
AnimationController controller;
Animation animation;
void initState() {
super.initState();
controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this);
animation = CurvedAnimation(parent: controller, curve: Curves.slowMiddle);
controller.forward();
animation.addListener(() => setState(() {}));
controller.addStatusListener((status) {
if (status == AnimationStatus.completed) controller.reverse(from: 400);
else if (status == AnimationStatus.dismissed) controller.forward();
});
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
margin: EdgeInsets.only(bottom: animation.value * 400),
width: 50,
height: 50,
color: Colors.red),
),
);
}
}
トゥイーン
数値だけでなく、トゥイーン(betweenの略)を使用して、色などの他の範囲を操作することもできます。 湾曲したアニメーションと同様に、コントローラーまたはアニメーションのラッパーとして機能し、色をその値に設定できます。
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
AnimationController controller;
Animation animation;
Animation changeColor;
void initState() {
super.initState();
controller =
AnimationController(duration: Duration(seconds: 1), vsync: this);
animation = CurvedAnimation(parent: controller, curve: Curves.slowMiddle);
changeColor = ColorTween(begin: Colors.red, end: Colors.blue).animate(animation);
controller.forward();
animation.addListener(() => setState(() {}));
controller.addStatusListener((status) {
if (status == AnimationStatus.completed) controller.reverse(from: 400);
else if (status == AnimationStatus.dismissed) controller.forward();
});
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
margin: EdgeInsets.only(bottom: animation.value * 400),
width: 50,
height: 50,
color: changeColor.value),
),
);
}
}
クロススクリーン
もう1つのすばらしいテクニックは、異なる画面上のウィジェット間でトランジションが必要な場合にHeroウィジェットを使用することです。 それぞれを、一致するタグを使用して独自のHeroウィジェットでラップする必要があります。 タグは一意である必要があり、画面上に複数存在することはできません。
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(height: 1),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Hero(tag: 'icon', child: Icon(Icons.add)),
]),
Navbar()
]));
}
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(height: 1),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
SizedBox(width: 1),
Hero(
tag: 'icon',
child: Icon(Icons.add, color: Colors.red, size: 75)),
]),
Navbar()
]),
);
}
結論
過去のほとんどのフロントエンドWebテクノロジーでは、アニメーションは後付けとして残されていましたが、この素晴らしいフレームワークを開発する際に、フラッターチームはアニメーションを念頭に置いて素晴らしい仕事をしました。 私たちは実際、Flutterがアニメーションに関してできることのほんの一部にすぎませんでした。