Flutter Advanced Animation Effect (6)

  • 2021-10-13 08:49:52
  • OfStack

In the last article, our previous definition of BarChart. lerp was not efficient, and the Bar instance we are creating is given only as a parameter of Bar. lerp, and is repeated for each value of the animation parameter t. 60 frames per second, which means that many Bar instances may be sent to the garbage collector, even for relatively short animations.

We can adopt the following three solutions:

The Bar instance can be reused by creating it only once in the Bar class instead of calling collapsed every time, but this approach is not suitable for our application. Reuse can be handled with BarChartTween by having its constructor create an BarTween instance of the list _ tween, using (i) = when creating the complement bar graph > _ tweens [i]. lerp (t). This approach breaks the convention of using the static method lerp, which does not involve any objects in BarChart. lerp and is used to store the complement list for the duration of the animation. On the contrary, the BarChartTween object is completely suitable for this 1 point. Assuming that there is appropriate conditional logic in Bar. lerp, null can be used to represent collapsible bars, which is very efficient, but care should be taken to avoid referencing or misunderstanding null. null is commonly used in Flutter SDK, where the static method lerp treats null as an animation endpoint, which is usually interpreted as some invisible element, such as a completely transparent color or a zero-size graphic element. In our code, lerpDouble treats null as zero unless both animation end points are null.

Taken together, let's use the last solution. First, we need to update part of the code of BarChart.


class BarChart {
 // ...
 static BarChart lerp(BarChart begin, BarChart end, double t) {
  final barCount = max(begin.bars.length, end.bars.length);
  final bars = new List.generate(
   barCount,
   (i) => Bar.lerp(begin._barOrNull(i), end._barOrNull(i), t)
  );
  return new BarChart(bars);
 }
 // ...
}

Then we need to update the conditional logic of Bar under 1.


class Bar {
 Bar(this.x, this.width, this.height, this.color);
 final double x;
 final double width;
 final double height;
 final Color color;

 static Bar lerp(Bar begin, Bar end, double t) {
  if(begin == null && end == null)
   return null;
  return new Bar(
    lerpDouble((begin??end).x, (end??begin).x, t),
    // ? Variable can be null
    lerpDouble(begin?.width, end?.width, t),
    lerpDouble(begin?.height, end?.height, t),
    Color.lerp((begin??end).color, (end??begin).color, t)
  );
 }
}

Now, in our application, how to write the judgment of using collapsed bars as invisible elements in the conditional logic of Bar. lerp, so as to achieve the desired high efficiency. From a different point of view, I don't know if you have found that the maintainability of the code is not as good as the previous version. This is why the solution that seems to be inefficient was chosen before. The choice between performance and maintainability needs to be measured before making a decision.


Related articles: