From 59aed9764775dbf8742e68a70c98eb5bf3b777e5 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Mon, 29 Jun 2020 20:20:32 -0400 Subject: [PATCH] Simplify the animation control for macrobenchmarks test case (#60412) * Simplify the animation control * Using AnimatedBuilder --- .../macrobenchmarks/lib/src/cubic_bezier.dart | 4 + .../macrobenchmarks/lib/src/cull_opacity.dart | 4 + .../lib/src/multi_widget_construction.dart | 120 +++++++++--------- 3 files changed, 65 insertions(+), 63 deletions(-) diff --git a/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart b/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart index 90ca20afd6d..6ce3c172422 100644 --- a/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart +++ b/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart @@ -312,6 +312,10 @@ class AnimatedBezierState extends State super.initState(); controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 1000)); + // Animations are typically implemented using the AnimatedBuilder widget. + // This code uses a manual listener for historical reasons and will remain + // in order to preserve compatibility with the history of measurements for + // this benchmark. curve = CurvedAnimation(parent: controller, curve: Curves.linear) ..addListener(() { setState(() {}); diff --git a/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart b/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart index 856a6859638..5b68085cb16 100644 --- a/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart +++ b/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart @@ -18,6 +18,10 @@ class _CullOpacityPageState extends State with SingleTickerProv super.initState(); _controller = AnimationController(vsync: this, duration: const Duration(seconds: 2)); + // Animations are typically implemented using the AnimatedBuilder widget. + // This code uses a manual listener for historical reasons and will remain + // in order to preserve compatibility with the history of measurements for + // this benchmark. _offsetY = Tween(begin: 0, end: -1000.0).animate(_controller)..addListener((){ setState(() {}); }); diff --git a/dev/benchmarks/macrobenchmarks/lib/src/multi_widget_construction.dart b/dev/benchmarks/macrobenchmarks/lib/src/multi_widget_construction.dart index b014f995b65..b21bd7550e1 100644 --- a/dev/benchmarks/macrobenchmarks/lib/src/multi_widget_construction.dart +++ b/dev/benchmarks/macrobenchmarks/lib/src/multi_widget_construction.dart @@ -5,11 +5,11 @@ import 'package:flutter/material.dart'; class MultiWidgetConstructTable extends StatefulWidget { - const MultiWidgetConstructTable(this.column, this.row, {Key key}) + const MultiWidgetConstructTable(this.columnCount, this.rowCount, {Key key}) : super(key: key); - final int column; - final int row; + final int columnCount; + final int rowCount; @override _MultiWidgetConstructTableState createState() => @@ -24,82 +24,76 @@ class _MultiWidgetConstructTableState extends State Colors.cyan, Colors.lightBlue, Colors.blue, Colors.indigo, Colors.purple, ]; int counter = 0; - Color baseColor = colorList[0][900]; - AnimationController controller; - CurvedAnimation curve; + AnimationController _controller; @override void initState() { super.initState(); - controller = AnimationController( - vsync: this, duration: const Duration(milliseconds: 10000)); - curve = CurvedAnimation(parent: controller, curve: Curves.linear) - ..addListener(() { - final double colorPosition = curve.value; - final int c1Position = (colorPosition * (colorList.length + 1)).floor(); - final Color c1 = colorList[c1Position % colorList.length][900]; - final Color c2 = colorList[(c1Position + 1) % colorList.length][900]; - setState(() { - baseColor = Color.lerp( - c1, c2, colorPosition * (colorList.length + 1) - c1Position); - }); - }) - ..addStatusListener((AnimationStatus state) { - if (state == AnimationStatus.completed) { - controller.reverse(); - } else if (state == AnimationStatus.dismissed) { - controller.reset(); - controller.forward(); - } - }); - - controller.forward(); + _controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 10000), + lowerBound: 0, + upperBound: colorList.length + 1.0, + )..repeat(); } @override void dispose() { - controller.dispose(); + _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - final int totalLength = widget.row * widget.column; - final int widgetCounter = counter * totalLength; - final double height = MediaQuery.of(context).size.height / widget.column; - counter++; - return Scaffold( - body: Table( - children: List.generate( - widget.row, - (int row) => TableRow( - children: List.generate( - widget.column, - (int column) { - final int label = row * widget.column + column; - return counter % 2 == 0 - ? Container( - // This key forces rebuilding the element - key: ValueKey(widgetCounter + label), - color: Color.lerp( - Colors.white, baseColor, label / totalLength), - child: Text('${widgetCounter + label}'), - constraints: BoxConstraints.expand(height: height), - ) - : MyContainer( - // This key forces rebuilding the element - key: ValueKey(widgetCounter + label), - color: Color.lerp( - Colors.white, baseColor, label / totalLength), - child: Text('${widgetCounter + label}'), - constraints: BoxConstraints.expand(height: height), - ); - }, + return AnimatedBuilder( + animation: _controller, + builder: (BuildContext context, _) { + final int totalLength = widget.rowCount * widget.columnCount; + final int widgetCounter = counter * totalLength; + final double height = MediaQuery.of(context).size.height / widget.rowCount; + final double colorPosition = _controller.value; + final int c1Position = colorPosition.floor(); + final Color c1 = colorList[c1Position % colorList.length][900]; + final Color c2 = colorList[(c1Position + 1) % colorList.length][900]; + final Color baseColor = Color.lerp(c1, c2, colorPosition - c1Position); + counter++; + return Scaffold( + body: Table( + children: List.generate( + widget.rowCount, + (int row) => TableRow( + children: List.generate( + widget.columnCount, + (int column) { + final int label = row * widget.columnCount + column; + // This implementation rebuild the widget tree for every + // frame, and is intentionally designed of poor performance + // for benchmark purposes. + return counter % 2 == 0 + ? Container( + // This key forces rebuilding the element + key: ValueKey(widgetCounter + label), + color: Color.lerp( + Colors.white, baseColor, label / totalLength), + child: Text('${widgetCounter + label}'), + constraints: BoxConstraints.expand(height: height), + ) + : MyContainer( + // This key forces rebuilding the element + key: ValueKey(widgetCounter + label), + color: Color.lerp( + Colors.white, baseColor, label / totalLength), + child: Text('${widgetCounter + label}'), + constraints: BoxConstraints.expand(height: height), + ); + }, + ), + ), ), ), - ), - ), + ); + }, ); } }