アニメーション(ImplicitlyAnimatedWidget)
アニメーション(ImplicitlyAnimatedWidget)
今回はアニメーション(ImplicitlyAnimatedWidget)について解説していきます。
アニメーションを作成する方法として、AnimatedContainerを使った方法もあるのですが、他にも色々と簡単に作成できる方法が提供されています。
AnimatedContainerの解説はこちら
ImplicitlyAnimatedWidgetクラスを継承しているとAnimateControllerなどのような複雑な制御をせずにアニメーションを作成できます。
- AnimatedAlign
- AnimatedPadding
- AnimatedSize
- AnimatedDefaultTextStyle
- AnimatedOpacity
- AnimatedPhysicalModel
- AnimatedPositioned
- AnimatedPositionedDirectional
配置の変更(AnimatedAlign)
「AnimatedAlign」を使うことで子要素の配置を変更してアニメーションさせることができます。
AnimatedContainerのAlignmentでも同じ動きを作ることができます。
class _MainPageState extends State<MainPage> {
Alignment _alg = Alignment.topLeft;
void _onTap() => setState(() => _alg = Alignment.bottomRight);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedAlign'),
),
body: AnimatedAlign(
alignment: _alg,
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100,
color: Colors.blueAccent,
),
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedAlignはalignment
で子要素の配置を変更します。
サンプルは、topLeft
の位置から、bottomRight
の位置へ斜めに移動しているのがわかると思います。
この時の、アニメーションの動き(Curve)や、時間(Duration)についてはAnimatedContainerで説明していますので、そちらを参照してください。
AnimatedPadding
「AnimatedPadding」を使うことでPaddingを変更してアニメーションさせることができます。
AnimatedContainerのPaddingでも同じ動きを作ることができます。
class _MainPageState extends State<MainPage> {
double _padding = 50;
void _onTap() => setState(() => _padding = 0);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedPadding'),
),
body: Center(
child: Container(
color: Colors.orange,
child: AnimatedPadding(
padding: EdgeInsets.all(_padding),
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100,
color: Colors.blueAccent,
),
),
),
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedPaddingはpadding
で余白を変更します。
サンプルは、Paddingを50
から、0
に変更しているので、オレンジ色の部分がなくなったのがわかると思います。
AnimatedSize
「AnimatedSize」を使うことでサイズの変更してアニメーションさせることができます。
AnimatedContainerのサイズ調整でも同じ動きを作ることができます。
画像などを子要素にすることもできるので、クリックすると画像が拡大されるようなアニメーションを作ることも可能です。
class _MainPageState extends State<MainPage> with SingleTickerProviderStateMixin {
double _width = 50;
void _onTap() => setState(() => _width = 100);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedSize'),
),
body: Center(
child: AnimatedSize(
vsync: this,
duration: Duration(seconds: 1),
child: Container(
width: _width,
height: 100,
color: Colors.blueAccent,
),
),
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedSizeはwidth
またはheight
の値を変更してアニメーションさせます。
サンプルは、width
を50
から、100
に変更しているので、横に大きくなり正方形に変わりました。
AnimatedDefaultTextStyle
「AnimatedDefaultTextStyle」を使うことでテキスト要素のアニメーションさせることができます。
テキストを目立たせたり動きのあるメッセージを作ることが可能です。
class _MainPageState extends State<MainPage> {
TextStyle _style = TextStyle(color: Colors.blueAccent, fontSize: 30, fontWeight: FontWeight.w900);
void _onTap() => setState(() => _style = TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.w300));
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedDefaultTextStyle'),
),
body: Center(
child: AnimatedDefaultTextStyle(
style: _style,
duration: Duration(seconds: 1),
child:Text('AnimatedDefaultTextStyle')
),
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedDefaultTextStyleはstyle
の値を変更してアニメーションさせます。
サンプルは、style
の「TextStyle」クラスの設定を変更することで、フォントのサイズや色、太さなどが変わっています。
AnimatedOpacity
「AnimatedOpacity」を使うことで色の濃さに対してのアニメーションさせることができます。
色の濃さをアニメーションすることで、フィードアウトやフィードインのようなアニメーションが簡単に作れます。
class _MainPageState extends State<MainPage> {
double _opacity = 1.0;
void _onTap() => setState(() => _opacity = 0.5);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedOpacity'),
),
body: Center(
child: AnimatedOpacity(
opacity: _opacity,
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100,
color: Colors.blueAccent,
),
),
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedOpacityはopacity
の値を変更してアニメーションさせます。
サンプルは、opacity
を1.0
から0.5
に変更することで、徐々に薄くなっていくアニメーションになっています。
AnimatedPhysicalModel
「AnimatedPhysicalModel」を使うことで影の濃さなどに対してのアニメーションさせることができます。
モーダルやボタンが浮き上がったり、沈み込むようなアニメーションを作ることができます。
class _MainPageState extends State<MainPage> {
bool _isDisabled = true;
void _onTap() => setState(() => _isDisabled = false);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedPhysicalModel'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(40),
child: AnimatedPhysicalModel(
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100
),
borderRadius: _isDisabled ? BorderRadius.all(Radius.zero) : BorderRadius.all(Radius.circular(10.0)),
elevation: _isDisabled ? 10 : 20,
color: _isDisabled ? Colors.orange : Colors.deepOrange,
animateColor: true,
shape: BoxShape.rectangle,
shadowColor: Colors.black,
curve: Curves.fastOutSlowIn,
),
),
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedPhysicalModelは borderRadius
とelevation
をアニメーションさせることができます。shape
はアニメーションしません。animateColor
をtrue
にすることで、色もアニメーションさせることができます。
サンプルは、 borderRadius
とelevation
、color
を変更することで、浮き上がって色が代わり角が取れるアニメーションになっています。
AnimatedPositioned
「AnimatedPositioned」を使うことで位置を変化をアニメーションさせることができます。
「AnimatedAlign」との違いは、四辺からの距離の指定で細かく移動させることができる点です。
class _MainPageState extends State<MainPage> {
double _top = 0;
void _onTap() => setState(() => _top = 100);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedPositioned'),
),
body: Center(
child: Stack(
children: <Widget>[
AnimatedPositioned(
top: _top,
left: 0,
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100,
color: Colors.blueAccent,
),
),
]
)
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedPositionedは以下の値を変更してアニメーションさせます。
top
上辺からの距離bottom
下辺からの距離left
左辺からの距離right
右辺からの距離
必ずStackの子要素である必要があります。
サンプルは、top
を0
から100
に変更することで、上から下へ移動するアニメーションになっています。
AnimatedPositionedDirectional
「AnimatedPositionedDirectional」を使うことで位置を変化をアニメーションさせることができます。
「AnimatedPositioned」との違いは、ほとんどありません。
違いとしては、横方向への動きがleft
、right
だったものが、start
、end
に変わっています。
これは、多言語化意識したときに特に有用な要素です。
例えばアラビア語のように文字の読む方向が、右から左になっているので、通常とは逆にstart
は右、end
は左になります。
このように国によって右から左、左から右など見る順が違うので、Directionalityの設定で、方向を容易に制御できるようになります。
class _MainPageState extends State<MainPage> {
double _start = 0;
void _onTap() => setState(() => _start = 100);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedPositionedDirectional'),
),
body: Center(
child: Stack(
children: <Widget>[
Directionality(
textDirection: TextDirection.rtl,
child: AnimatedPositionedDirectional(
top: 0,
start: _start,
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100,
color: Colors.blueAccent,
),
),
)
]
)
),
floatingActionButton: FloatingActionButton(onPressed: _onTap),
);
}
}
AnimatedPositionedDirectionalは以下の値を変更してアニメーションさせます。
top
上辺からの距離bottom
下辺からの距離start
開始位置からの距離end
終了位置からの距離
必ずStackの子要素である必要があります。
サンプルは、start
を0
から100
に変更することで、開始位置から、終了位置へ移動するアニメーションになっています。
サンプルは、Directionality.rtl
(右から左)となっているので、右を0
として左側へ100
移動しています。