TweenAnimationBuilderを使ってみる。
とりあえず動くサンプル
import 'package:flutter/material.dart'; void main() { return runApp( MaterialApp( home: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body:TweenAnimationBuilder( curve:Curves.slowMiddle, //←curveを指定できる。 duration:Duration(seconds:4), tween:ColorTween(begin:Colors.white,end:Colors.pinkAccent,), builder:(BuildContext _,Color value,Widget child){ return ColorFiltered( child:Image.asset('assets/images/diamond.png'), colorFilter:ColorFilter.mode( value, BlendMode.modulate, ), ); }, ), ); } }
ColorFiltered使わないパターン
import 'package:flutter/material.dart'; void main() { return runApp( MaterialApp( home: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: TweenAnimationBuilder( curve: Curves.easeIn, duration: Duration(seconds: 4), tween: ColorTween( begin: Colors.white, end: Colors.pinkAccent, ), builder: (BuildContext _, Color? value, Widget? child) { return Image.asset( 'assets/images/diamond.png', color: value, colorBlendMode: BlendMode.colorBurn, ); }, ), ); } }
→
動画で説明されているようにonEndパラメータを設定してオレンジへの遷移が終了したらグリーンへの遷移が始まるようにする。
リビルドでオレンジ→グリーンの遷移が起こるのでStatefulWidgetにする必要がある。
import 'package:flutter/material.dart'; void main() { return runApp( MaterialApp( home: MyApp(), ), ); } class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { Color _colorValue = Colors.orange; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: TweenAnimationBuilder( curve: Curves.easeIn, duration: Duration(seconds: 1), tween: ColorTween( begin: Colors.white, end: _colorValue, ), builder: (BuildContext _, Color? value, Widget? child) { return Image.asset( 'assets/images/diamond.png', color: value, colorBlendMode: BlendMode.colorBurn, ); }, onEnd:()=>setState( ()=>_colorValue=Colors.green, ), ), ), ); } }
→
→
動画でchildプロパティを使うとパフォーマンス最適化されますよね、みたいな説明があるので、試しにbuildメソッド呼び出し回数を数えてみる。
まずchildプロパティ使わないパターン。
import 'package:flutter/material.dart'; void main() { return runApp( MaterialApp( home: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body:TweenAnimationBuilder( curve:Curves.slowMiddle, duration:Duration(seconds:1), tween:ColorTween(begin:Colors.white,end:Colors.pinkAccent,), builder:(BuildContext _,Color? value,Widget? child){ return ColorFiltered( child:DiamondImage(), colorFilter:ColorFilter.mode( value!, BlendMode.modulate, ), ); }, ), ); } } class DiamondImage extends StatefulWidget { const DiamondImage({ Key? key, }) : super(key: key); @override _DiamondImageState createState() => _DiamondImageState(); } class _DiamondImageState extends State<DiamondImage> { int n=0; @override Widget build(BuildContext context) { n++; print("build呼び出し:$n回目"); return Image.asset('assets/images/diamond.png'); } }
1秒間で59回buildメソッドが呼び出された。
次にchildプロパティを使うパターン。
import 'package:flutter/material.dart'; void main() { return runApp( MaterialApp( home: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body:TweenAnimationBuilder( curve:Curves.slowMiddle, duration:Duration(seconds:1), tween:ColorTween(begin:Colors.white,end:Colors.pinkAccent,), builder:(BuildContext _,Color? value,Widget? child){ return ColorFiltered( child:child, colorFilter:ColorFilter.mode( value!, BlendMode.modulate, ), ); }, child:DiamondImage(), ), ); } } class DiamondImage extends StatefulWidget { const DiamondImage({ Key? key, }) : super(key: key); @override _DiamondImageState createState() => _DiamondImageState(); } class _DiamondImageState extends State<DiamondImage> { int n=0; @override Widget build(BuildContext context) { n++; print("build呼び出し:$n回目"); return Image.asset('assets/images/diamond.png'); } }
buildメソッドの呼び出しは1回のみ。
ということで最適化されている、というお話。