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

119 篇文章 9 订阅
82 篇文章 1416 订阅

在上一篇文章:Flutter进阶—实现动画效果(二)的最后,我们实现了一个控件,其中包含各种布局和状态处理控件。以及使用自定义的动画感知绘图代码绘制单个Bar的控件。还有一个浮动按钮控件,用于启动条形图高度的动画变化。

现在开始向我们的单个条形添加颜色,在Bar类的height字段下添加一个color字段,并且更新Bar.lerp以使其两者兼容。在上一篇文章中,介绍过“lerp”是“线性内插”或“线性插值”的一种简短形式。

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)
    );
  }
}

要在我们的应用程序中使用彩色条形,需要更新BarChartPainter以从Bar获取条形颜色。

class BarChartPainter extends CustomPainter {
  // ...
  @override
  void paint(Canvas canvas, Size size) {
    final bar = animation.value;
    final paint = new Paint()
      // 从Bar获取条形颜色
      ..color = bar.color
      ..style = PaintingStyle.fill;
    // ...
  // ...
  }

在main.dart同级目录下新建color_palette.dart文件,用于获取颜色。

import 'package:flutter/material.dart';
import 'dart:math';

class ColorPalette {
  static final ColorPalette primary = new ColorPalette(<Color>[
    Colors.blue[400],
    Colors.red[400],
    Colors.green[400],
    Colors.yellow[400],
    Colors.purple[400],
    Colors.orange[400],
    Colors.teal[400],
  ]);

  ColorPalette(List<Color> colors) : _colors = colors {
    // bool isNotEmpty:如果此集合中至少有一个元素,则返回true
    assert(colors.isNotEmpty);
  }

  final List<Color> _colors;

  Color operator [](int index) => _colors[index % length];

  // 返回集合中的元素数量
  int get length => _colors.length;

  /*
  int nextInt(
    int max
  )
  生成一个非负随机整数,范围从0到max(包括max)
   */
  Color random(Random random) => this[random.nextInt(length)];
}

我们将把Bar.empty和Bar.random工厂构造函数放在Bar上。

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

  factory Bar.empty() => new Bar(0.0, Colors.transparent);
  factory Bar.random(Random random) {
    return new Bar(
      random.nextDouble() * 100.0,
      ColorPalette.primary.random(random)
    );
  }

  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)
    );
  }
}

在main.dart中,我们需要创建一个空的Bar和一个随机的Bar。我们将为前者使用完全透明的颜色,后者将使用随机颜色。

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  // ...
  @override
  void initState() {
    // ...
    tween = new BarTween(new Bar.empty(), new Bar.random(random));
    animation.forward();
  }
  // ...
  void changeData() {
    setState(() {
      tween = new BarTween(
        tween.evaluate(animation),
        new  Bar.random(random),
      );
      animation.forward(from: 0.0);
    });
  }
  // ...
}

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

这里写图片描述

未完待续~~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何小有

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值