国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫(huà)效果(五)

2019-10-21 21:40:50
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

在本篇文章開(kāi)始前,我們先來(lái)回顧一下之前我們都做了哪些事情。在第一篇文章中,我們?cè)趧?dòng)畫(huà)值更改時(shí)調(diào)用double lerpDouble(num a, num b, double t)重新繪制條形。在第二篇文章中,我們首先用Tween類幫助我們管理動(dòng)畫(huà)值,并重新繪制條形,然后把繪制條形動(dòng)畫(huà)相關(guān)的類提取到bar.dart文件。在第三篇文章中,我們首先在Bar類中增加顏色的字段,再新建color_palette.dart文件,用于獲取顏色值,同時(shí)用工廠構(gòu)造函數(shù)Bar.empty和Bar.random分別創(chuàng)建空白Bar實(shí)例和隨機(jī)Bar實(shí)例。在第四篇文章中,我們新增了BarChart類,用于創(chuàng)建指定數(shù)量的Bar實(shí)例列表,并將繪制條形的代碼更改為繪制條形圖。

接下來(lái),我們?yōu)锽ar類增加x坐標(biāo)和寬度屬性,然后我們使BarChart支持具有不同列數(shù)的圖表。我們的新圖表將適用于數(shù)據(jù)集,其中bar i代表某些系列中的第i個(gè)值,如產(chǎn)品發(fā)布后第i天的銷(xiāo)售額。這樣的圖表涉及0..n個(gè)條形,但一個(gè)圖表的條形數(shù)量n可能不同于下一個(gè)圖表。

比如有兩個(gè)圖表,分別有5個(gè)和7個(gè)條形。5個(gè)條形的表格可以按照之前的方法進(jìn)行動(dòng)畫(huà)化。bars的索引5和6在另一個(gè)動(dòng)畫(huà)終點(diǎn)沒(méi)有對(duì)方,但是現(xiàn)在我們可以自由地給每個(gè)條形自己的位置和寬度,我們可以引入兩個(gè)不可見(jiàn)的條形來(lái)扮演這個(gè)角色。視覺(jué)上效果是隨著動(dòng)畫(huà)的進(jìn)行,bars的索引5和6成長(zhǎng)為最終的外觀。如果是相反方向的動(dòng)畫(huà),則bars的索引5和6將會(huì)減弱或淡入隱形。

復(fù)合值之間的線性插值(lerp)通過(guò)相應(yīng)的組件相關(guān)聯(lián),如果某個(gè)組件在一個(gè)終點(diǎn)丟失,則在其位置使用一個(gè)不可見(jiàn)組件。通常有幾種方法來(lái)選擇不可見(jiàn)的組件,假設(shè)我們的產(chǎn)品經(jīng)理決定使用零寬度、零高度的條形,其x坐標(biāo)和顏色從其可見(jiàn)對(duì)象繼承,我們將為Bar添加一個(gè)方法來(lái)創(chuàng)建給定實(shí)例的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():返回不大于此的最大整數(shù) 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:返回兩個(gè)數(shù)字中較大的一個(gè) final barCount = max(begin.bars.length, end.bars.length); final bars = new List.generate(  barCount,  (i) => Bar.lerp(  // ??:如果為空時(shí)取的默認(rèn)值  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, 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, t),  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 { 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;}

將上述代碼整合到我們的應(yīng)用程序中,包括為此新設(shè)置重新定義BarChart.random和BarChart.empty。現(xiàn)在可以合理地使用空白圖表來(lái)包含空?qǐng)D表零條形,而隨機(jī)的條形圖可以包含所有相同隨機(jī)顏色的隨機(jī)數(shù)量的條形,并且每個(gè)具有隨機(jī)選擇的高度。但是由于位置和寬度現(xiàn)在是Bar定義的一部分,我們需要BarChart.random來(lái)指定這些屬性。為BarChart.random提供圖表Size參數(shù)是合理的,可以緩解BarChartPainter.paint的大部分計(jì)算。

最后我們需要更新main.dart文件,讓我們的應(yīng)用程序可以重新顯示。

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,動(dòng)畫(huà)效果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 五指山市| 青冈县| 丰宁| 海南省| 娄底市| 深泽县| 贵溪市| 临桂县| 博白县| 刚察县| 自治县| 茂名市| 苗栗市| 资源县| 贵定县| 大安市| 克东县| 宁阳县| 石阡县| 陇川县| 蓝田县| 崇州市| 二手房| 麦盖提县| 沙雅县| 曲周县| 澄江县| 澄迈县| 娱乐| 云南省| 定兴县| 新田县| 台中市| 马鞍山市| 宜川县| 江安县| 四川省| 凤台县| 吴桥县| 宝兴县| 阜平县|