Flutter进阶—实现动画效果(五)

Flutter进阶—实现动画效果(五),第1张

概述在本篇文章开始前,我们先来回顾一下之前我们都做了哪些事情。在第一篇文章中,我们在动画值更改时调用double lerpDouble(num a, num b, double t)重新绘制条形。在第二篇文章中,我们首先用Tween类帮助我们管理动画值,并重新绘制条形,然后把绘制条形动画相关的类提取到bar.dart文件。在第三篇文章中,我们首先在Bar类中增加颜色的字段,再新建color_palet

在本篇文章开始前,我们先来回顾一下之前我们都做了哪些事情。在第一篇文章中,我们在动画值更改时调用double lerpDouble(num a,num b,double t)重新绘制条形。在第二篇文章中,我们首先用Tween类帮助我们管理动画值,并重新绘制条形,然后把绘制条形动画相关的类提取到bar.dart文件。在第三篇文章中,我们首先在bar类中增加颜色的字段,再新建color_palette.dart文件,用于获取颜色值,同时用工厂构造函数bar.empty和bar.random分别创建空白bar实例和随机bar实例。在第四篇文章中,我们新增了barChart类,用于创建指定数量的bar实例列表,并将绘制条形的代码更改为绘制条形图。

接下来,我们为bar类增加x坐标和宽度属性,然后我们使barChart支持具有不同列数的图表。我们的新图表将适用于数据集,其中bar i代表某些系列中的第i个值,如产品发布后第i天的销售额。这样的图表涉及0..n个条形,但一个图表的条形数量n可能不同于下一个图表。

比如有两个图表,分别有5个和7个条形。5个条形的表格可以按照之前的方法进行动画化。bars的索引5和6在另一个动画终点没有对方,但是现在我们可以自由地给每个条形自己的位置和宽度,我们可以引入两个不可见的条形来扮演这个角色。视觉上效果是随着动画的进行,bars的索引5和6成长为最终的外观。如果是相反方向的动画,则bars的索引5和6将会减弱或淡入隐形。

复合值之间的线性插值(lerp)通过相应的组件相关联,如果某个组件在一个终点丢失,则在其位置使用一个不可见组件。通常有几种方法来选择不可见的组件,假设我们的产品经理决定使用零宽度、零高度的条形,其x坐标和颜色从其可见对象继承,我们将为bar添加一个方法来创建给定实例的collapsed版本。

import 'package:Flutter/material.dart';import 'package:Flutter/animation.dart';import 'dart:ui' show lerpDouble;import 'dart:math';import 'color_palette.dart';class barChart {  final List<bar> bars;  barChart(this.bars);  factory barChart.empty(Size size) {    return new barChart(<bar>[]);  }  factory barChart.random(Size size,Random random) {    const barWIDthFraction = 0.75;    const minbardistance = 20.0;    // floor():返回不大于此的最大整数    final barCount = random.nextInt((size.wIDth/minbardistance).floor()) + 1;    final bardistance = size.wIDth / (1+barCount);    final barWIDth = bardistance * barWIDthFraction;    final startX = bardistance - barWIDth/2;    final color = colorPalette.primary.random(random);    final bars = new List.generate(      barCount,(i)=> new bar(        startX + i * bardistance,barWIDth,random.nextDouble() * size.height,color,),);    return new barChart(bars);  }  static barChart lerp(barChart begin,barChart end,double t) {    // max:返回两个数字中较大的一个    final barCount = max(begin.bars.length,end.bars.length);    final bars = new List.generate(      barCount,(i) => bar.lerp(        // ??:如果为空时取的默认值        begin._barOrNull(i) ?? end.bars[i].collapsed,end._barOrNull(i) ?? begin.bars[i].collapsed,t,)    );    return new barChart(bars);  }  bar _barOrNull(int index) => (index<bars.length ? bars[index] : null);}class barChartTween extends Tween<barChart> {  barChartTween(barChart begin,barChart end) : super(begin: begin,end: end);  @overrIDe  barChart lerp(double t) => barChart.lerp(begin,end,t);}class bar {  bar(this.x,this.wIDth,this.height,this.color);  final double x;  final double wIDth;  final double height;  final color color;  bar get collapsed => new bar(x,0.0,color);  static bar lerp(bar begin,bar end,double t) {    return new bar(        lerpDouble(begin.x,end.x,t),lerpDouble(begin.wIDth,end.wIDth,lerpDouble(begin.height,end.height,color.lerp(begin.color,end.color,t)    );  }}class barTween extends Tween<bar> {  barTween(bar begin,bar end) : super(begin: begin,end: end);  @overrIDe  bar lerp(double t) => bar.lerp(begin,t);}class barChartPainter extends CustomPainter {  barChartPainter(Animation<barChart> animation)      : animation = animation,super(repaint: animation);  final Animation<barChart> animation;  @overrIDe  voID paint(Canvas canvas,Size size) {    final paint = new Paint()..style = PaintingStyle.fill;    final chart = animation.value;    for(final bar in chart.bars) {      paint.color = bar.color;      canvas.drawRect(        new Rect.fromLTWH(          bar.x,size.height - bar.height,bar.wIDth,bar.height        ),paint      );    }  }  @overrIDe  bool shouldRepaint(barChartPainter old) => false;}

将上述代码整合到我们的应用程序中,包括为此新设置重新定义barChart.random和barChart.empty。现在可以合理地使用空白图表来包含空图表零条形,而随机的条形图可以包含所有相同随机颜色的随机数量的条形,并且每个具有随机选择的高度。但是由于位置和宽度现在是bar定义的一部分,我们需要barChart.random来指定这些属性。为barChart.random提供图表Size参数是合理的,可以缓解barChartPainter.paint的大部分计算。

最后我们需要更新main.dart文件,让我们的应用程序可以重新显示。

class _MyHomePageState extends State<MyHomePage> with TickerProvIDerStateMixin {  static const size = const Size(200.0,100.0);  // ...  @overrIDe  voID initState() {    // ...    tween = new barChartTween(      new barChart.empty(size),new barChart.random(size,random));    animation.forward();  }  // ...  voID changeData() {    setState(() {      tween = new barChartTween(        tween.evaluate(animation),new  barChart.random(size,random),);      animation.forward(from: 0.0);    });  }  // ...  }}

未完待续~~~

总结

以上是内存溢出为你收集整理的Flutter进阶—实现动画效果(五)全部内容,希望文章能够帮你解决Flutter进阶—实现动画效果(五)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1002636.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存