Flutter   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Flutter进阶—实现动画效果(十)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

前面的两篇文章动画效果(八)动画效果(九)】中,我们只需要统计产品和地区,如果现在增加一个统计项目——销售渠道,那么使用之前的堆叠条形图和分组条形图都不适合。我们可以将两者结合,使用分组+堆叠条形图,实际效果如下图所示:

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

如上图,我们使用同一种颜色的不同透明度表示不同的销售渠道,为了实现不同的透明度,我们需要先更新一下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 {
    assert(colors.isnotEmpty);
  }

  factory ColorPalette.monochrome(Color base,int length) {
    return new ColorPalette(
      new List.generate(
        length,(i) => _brighterColor(base,i,length)
      )
    );
  }

  static Color _brighterColor(Color base,int i,int n) {
    /* const color.fromARGB( int a,int r,int g,int b ) 从四个整数的低8位构造一个颜色 a:a是alpha值,0是透明的,255是完全不透明的 r:r为红色,从0到255 g:g为红色,从0到255 b:b为红色,从0到255 */
    return new Color.fromARGB(
      /* int alpha 这个颜色的alpha通道是8位值 值为0表示此颜色完全透明。值为255表示此颜色完全不透明 */
      base.alpha,_brighterComponent(base.red,n),_brighterComponent(base.green,_brighterComponent(base.blue,n)
    );
  }

  static int _brighterComponent(int base,int n) {
    return (base + i * (255 - base) / n).floor();
  }

  final List<Color> _colors;

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

  int get length => _colors.length;

  Color random(Random random) => this[random.nexTint(length)];
}

最后我们再更新一下bar.dart文件代码

import 'package:Flutter/material.dart';
import 'package:Flutter/animation.dart';
import 'dart:ui' show lerpDouble;
import 'dart:math';
import 'color_palette.dart';
import 'tween.dart';

class BarChart {
  BarChart(this.groups);

  final List<BarGroup> groups;

  factory BarChart.empty(Size sizE) {
    return new BarChart(<BarGroup>[]);
  }

  factory BarChart.random(Size size,Random random) {
    const groupWidthFraction = 0.75;
    const stackWidthFraction = 0.9;
    final groupRanks = _SELEctRanks(random,5);
    final groupCount = groupRanks.length;
    final groupDistance = size.width / (1+groupCount);
    final groupWidth = groupDistance * groupWidthFraction;
    final startX = groupDistance - groupWidth/2;
    final stackRanks = _SELEctRanks(random,ColorPalette.priMary.length ~/ 2);
    final stackCount = stackRanks.length;
    final stackDistance = groupWidth / stackCount;
    final stackWidth = stackDistance * stackWidthFraction;
    final groups = new List.generate(
      groupCount,(i) {
        final stacks = new List.generate(
          stackCount,(j) {
            final baseColor = ColorPalette.priMary[stackRanks[j]];
            final barRanks = _SELEctRanks(random,4);
            final monochrome = new ColorPalette.monochrome(baseColor,4);
            final bars = new List.generate(
              barRanks.length,(k) => new Bar(
                barRanks[k],random.nextDouble() * size.height / 2,monochrome[barRanks[k]],)
            );
            return new BarStack(
              stackRanks[j],baseColor,startX + i * groupDistance + j * stackDistance,stackWidth,bars,);
          }
        );
        return new BarGroup(
          groupRanks[i],stacks
        );
      }
    );
    return new BarChart(groups);
  }

  static List<int> _SELEctRanks(Random random,int cap) {
    final ranks = <int>[];
    var rank = 0;
    while(true) {
      rank += random.nexTint(2);
      if(cap <= rank) break;
      ranks.add(rank);
      rank++;
    }
    return ranks;
  }

}

class BarChartTween extends Tween<BarChart> {
  BarChartTween(BarChart begin,BarChart end)
    : _groupsTween = new MergeTween<BarGroup>(begin.groups,end.groups),super(begin: begin,end: end);

  final MergeTween<BarGroup> _groupsTween;

  @override
  BarChart lerp(double t) => new BarChart(_groupsTween.lerp(t));
}

class BarGroup implements @H_254_121@mergeTweenable<BarGroup> {
  BarGroup(this.rank,this.stacks);

  final int rank;
  final List<BarStack> stacks;

  @override
  BarGroup get empty => new BarGroup(rank,<BarStack>[]);

  @override
  bool operator <(BarGroup other) => rank < other.rank;

  @override
  Tween<BarGroup> tweenTo(BarGroup other) => new BarGroupTween(this,other);
}

class BarGroupTween extends Tween<BarGroup> {
  BarGroupTween(BarGroup begin,BarGroup end)
    : _stacksTween = new MergeTween<BarStack>(begin.stacks,end.stacks),end: end) {
      assert(begin.rank == end.rank);
    }

  final MergeTween<BarStack> _stacksTween;

  @override
  BarGroup lerp(double t) => new BarGroup(
    begin.rank,_stacksTween.lerp(t)
  );
}

class BarStack implements @H_254_121@mergeTweenable<BarStack> {
  BarStack(this.rank,this.baseColor,this.x,this.width,this.bars);
  final int rank;
  final Color baseColor;
  final double x;
  final double width;
  final List<Bar> bars;

  @override
  BarStack get empty => new BarStack(rank,x,0.0,<Bar>[]);

  @override
  bool operator <(BarStack other) => rank < other.rank;

  @override
  Tween<BarStack> tweenTo(BarStack other) => new BarStackTween(this,other);
}

class BarStackTween extends Tween<BarStack> {
  BarStackTween(BarStack begin,BarStack end)
    : _barsTween = new MergeTween<Bar>(begin.bars,end.bars),end: end) {
    assert(begin.rank == end.rank);
  }

  final MergeTween<Bar> _barsTween;

  @override
  BarStack lerp(double t) => new BarStack(
    begin.rank,Color.lerp(begin.baseColor,end.baseColor,t),lerpDouble(begin.x,end.x,lerpDouble(begin.width,end.width,_barsTween.lerp(t)
  );
}

class Bar extends @H_254_121@mergeTweenable<Bar> {
  Bar(this.rank,this.height,this.color);
  final int rank;
  final double height;
  final Color color;

  @override
  Bar get empty => new Bar(rank,color);

  @override
  bool operator <(Bar other) => rank < other.rank;

  @override
  Tween<Bar> tweenTo(Bar other) => new BarTween(this,other);

  static Bar lerp(Bar begin,Bar end,double t) {
    assert(begin.rank == end.rank);
    return new Bar(
      begin.rank,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) {
    assert(begin.rank == end.rank);
  }

  @override
  Bar lerp(double t) => Bar.lerp(begin,end,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 barPaint = new Paint()..style = PainTingStyle.fill;
    final linePaint = new Paint()
      ..style = PainTingStyle.stroke
      ..color = Colors.white
      ..strokeWidth = 1.0;
    final linePath = new Path();
    final chart = animation.value;
    for(final group in chart.groups) {
      for(final stack in group.stacks) {
        var y = size.height;
        for(final bar in stack.bars) {
          barPaint.color = bar.color;
          canvas.drawRect(
            new Rect.fromLTWH(
              stack.x,y - bar.height,stack.width,bar.height
            ),barPaint
          );
          if(y < size.height) {
            linePath.moveTo(stack.x,y);
            linePath.lineTo(stack.x + stack.width,y);
          }
          y -= bar.height;
        }
        canvas.drawPath(
          linePath,linePaint
        );
        linePath.reset();
      }
    }
  }

  @override
  bool shouldRepaint(BarChartPainter old) => false;
}

关于如何实现动画效果的教程到这里就暂时告一段落了~~~

大佬总结

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

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。