📜
【Dart/Flutter】AnimatedWidgetを自作する簡単例(extends AnimatedWidget)
AnimationController型変数を引数に渡し、AnimatedWidgetを継承したクラスを返す、簡単な例となります。
【Dart/Flutter】AnimatedWidgetを自作する簡単例(extends AnimatedWidget)
-
実行環境
-
DartPadやAndroid Studio等で実行
- Based on Flutter 3.7.7 Dart SDK 2.19.4
-
DartPadやAndroid Studio等で実行
-
参考
-
Widget catalog | Flutter
- 上記サイトの簡単な例バージョン
-
AnimatedWidget class - widgets library - Dart API
- A widget that rebuilds when the given Listenable changes value.
- 指定された Listenable の値が変更されたときに再構築されるウィジェット
- A widget that rebuilds when the given Listenable changes value.
-
Widget catalog | Flutter
AnimatedBuilder抽出前
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const Scaffold(body: MyHomePage()),
),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late AnimationController _animation;
void initState() {
super.initState();
_animation = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
)..repeat();
}
void dispose() {
_animation.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Stack(
alignment: AlignmentDirectional.center,
children: <Widget>[
AnimatedBuilder(
animation: _animation,
builder: (_, __) {
return Container(
color: Colors.red,
height: 1000 * _animation.value,
);
},
),
],
);
}
}
AnimatedBuilder抽出(自作クラス作成)
- 通常通りIDEの機能等により抽出すると、以下StatelessWidget
class TestTransition extends StatelessWidget {
const TestTransition({
Key? key,
required AnimationController animation,
}) : _animation = animation, super(key: key);
final AnimationController _animation;
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (_, __) {
return Container(
color: Colors.red,
height: 1000 * _animation.value,
);
},
);
}
}
- AnimatedWidgetとするための修正
- 継承変更
-
extends StatelessWidget
→extends AnimatedWidget
-
- 親コンストラクタにlistenable追加
-
super(key: key);
→super(key: key, listenable: animation);
-
- build関数内
- AnimatedBuilderを削除し、上記アニメーション用の変数を利用したWidgetに変更
-
return AnimatedBuilder(...);
→return Container(...);
-
- AnimatedBuilderを削除し、上記アニメーション用の変数を利用したWidgetに変更
- 継承変更
class TestTransition extends AnimatedWidget {
const TestTransition({
Key? key,
required AnimationController animation,
}) : _animation = animation,
super(key: key, listenable: animation);
final AnimationController _animation;
Widget build(BuildContext context) {
return Container(
color: Colors.red,
height: 1000 * _animation.value,
);
}
}
- 【参考】引数をthisとする場合 ※同様動作
class TestTransition extends AnimatedWidget {
const TestTransition({
Key? key,
required this.animation,
}) : super(key: key, listenable: animation);
final AnimationController animation;
Widget build(BuildContext context) {
return Container(
color: Colors.red,
height: 1000 * animation.value,
);
}
}
- 【参考】参考サイトでは、以下build関数内にアニメーション用の変数を追加 ※同様動作
AnimationController animation = listenable as AnimationController;
class TestTransition extends AnimatedWidget {
const TestTransition({
Key? key,
required AnimationController animation,
}) : super(key: key, listenable: animation);
Widget build(BuildContext context) {
AnimationController animation = listenable as AnimationController;
return Container(
color: Colors.red,
height: 1000 * animation.value,
);
}
}
以下、全文
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const Scaffold(body: MyHomePage()),
),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late AnimationController _animation;
void initState() {
super.initState();
_animation = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
)..repeat();
}
void dispose() {
_animation.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Stack(
alignment: AlignmentDirectional.center,
children: <Widget>[
TestTransition(animation: _animation),
],
);
}
}
class TestTransition extends AnimatedWidget {
const TestTransition({
Key? key,
required this.animation,
}) : super(key: key, listenable: animation);
final AnimationController animation;
Widget build(BuildContext context) {
return Container(
color: Colors.red,
height: 1000 * animation.value,
);
}
}
【備考】child利用
class TestTransition extends AnimatedWidget {
const TestTransition({
Key? key,
required AnimationController animation,
required this.child,
}) : super(key: key, listenable: animation);
final Widget child;
Widget build(BuildContext context) {
AnimationController animation = listenable as AnimationController;
return Container(
color: Colors.red,
height: 1000 * animation.value,
child: child,
);
}
}
Discussion