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

来源:互联网 发布:彩票分析软件下载 编辑:程序博客网 时间:2024/06/05 00:09

在上一篇文章:Flutter进阶—实现动画效果(三)中,实现了一个随机高度、颜色的条形。这一篇文章我们会实现多个条形,同样是随机高度、颜色。

首先在bar.dart中创建BarChart类,并使用固定长度的Bar实例列表。我们将使用5个条形,表示一周的5个工作日。然后,我们需要将创建空白和随机实例的责任从Bar转移到BarChart。

import 'package:flutter/material.dart';import 'package:flutter/animation.dart';import 'dart:ui' show lerpDouble;import 'dart:math';import 'color_palette.dart';class BarChart {  static const int barCount = 5;  final List<Bar> bars;  BarChart(this.bars) {    assert(bars.length == barCount);  }  factory BarChart.empty() {    return new BarChart(      /*      List.filled(        int length,        E fill, {          bool growable: false        }      )      创建给定长度的固定长度列表,并用fill在每个位置初始化值      length必须是非负整数       */      new List.filled(        barCount,        new Bar(0.0, Colors.transparent)      )    );  }  factory BarChart.random(Random random) {    final Color color = ColorPalette.primary.random(random);    return new BarChart(      /*      List.generate(        int length,        E generator(          int index        ), {        bool growable: true        }      )      创建给定长度的固定长度列表,并用generator创建的值在每个位置初始化值      创建的列表是固定长度,除非growable为true       */      new List.generate(        barCount,        (i) => new Bar(          random.nextDouble()*100.0,          color        )      )    );  }  static BarChart lerp(BarChart begin, BarChart end, double t) {    return new BarChart(      new List.generate(        barCount,        (i) => Bar.lerp(begin.bars[i], end.bars[i], t)      )    );  }}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.height, this.color);  final double height;  final Color color;  static Bar lerp(Bar begin, Bar end, double t) {    return new Bar(        lerpDouble(begin.height, end.height, t),        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, end, t);}class BarChartPainter extends CustomPainter {  static const barWidthFraction = 0.75;  BarChartPainter(Animation<BarChart> animation)      : animation = animation,        super(repaint: animation);  final Animation<BarChart> animation;  @override  void paint(Canvas canvas, Size size) {    void drawBar(Bar bar, double x, double width, Paint paint) {      paint.color = bar.color;      canvas.drawRect(        new Rect.fromLTWH(          x,          size.height-bar.height,          width,          bar.height        ),        paint      );    }    /*    Paint:Canvas绘制时使用的样式说明      style:是否绘制内部的形状、形状的边缘或两者都有,默认为PaintingStyle.fill     */    final paint = new Paint()..style = PaintingStyle.fill;    final chart = animation.value;    //  每个条形占用的空间宽度    final barDistance = size.width/(1+chart.bars.length);    // 每个条形占用空间75%的宽度    final barWidth = barDistance*barWidthFraction;    // 用于计算每个条形的x坐标点    var x = barDistance-barWidth/2;    for (final bar in chart.bars) {      drawBar(bar, x, barWidth, paint);      x += barDistance;    }  }  @override  bool shouldRepaint(BarChartPainter old) => false;}

BarChartPainter在条形之间均匀分配可用宽度,并使每个条形占用可用宽度的75%。接下来我们要更新main.dart,用BarChart、BarChartTween替换Bar、BarTween。

// ...class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {  final random = new Random();  AnimationController animation;  BarChartTween tween;  @override  void initState() {    super.initState();    animation = new AnimationController(        duration: const Duration(milliseconds: 300),        vsync: this    );    tween = new BarChartTween(new BarChart.empty(), new BarChart.random(random));    animation.forward();  }  @override  void dispose() {    animation.dispose();    super.dispose();  }  void changeData() {    setState(() {      tween = new BarChartTween(        tween.evaluate(animation),        new  BarChart.random(random),      );      animation.forward(from: 0.0);    });  }  @override  Widget build(BuildContext context) {    return new Scaffold(      body: new Center(          child: new CustomPaint(              size: new Size(200.0, 100.0),              painter: new BarChartPainter(tween.animate(animation))          )      ),      floatingActionButton: new FloatingActionButton(        onPressed: changeData,        child: new Icon(Icons.refresh),      ),    );  }}

现在应用程序的效果如下图:

这里写图片描述

未完待续~~~

原创粉丝点击