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

首頁 > 系統 > Android > 正文

Flutter進階之實現動畫效果(二)

2019-10-21 21:40:56
字體:
來源:轉載
供稿:網友

在上一篇文章:Flutter進階—實現動畫效果(一)的最后,我們說到需要一個處理程序混亂的概念。在這一篇文章中,我們會引入補間,它是構建動畫代碼的一個非常簡單的概念,主要作用是用面向對象的方法替代之前面向過程的方法。tween是一個值,它描述了其他值的空間中的兩個點之間的路徑,比如條形圖的動畫值從0運行到1。

補間在Dart中表示類型為Tween的對象

abstract class Tween<T> { final T begin; final T end; Tween(this.begin, this.end); T lerp(double t);}

術語lerp來自計算機圖形學領域,是線性插值(作為名詞)和線性內插(作為動詞)的縮寫。參數t是動畫值,補間應該從begin(當t為0時)到end(當t為1時)。

FlutterSDK的Tween類與Dart非常相似,但是一個支持變化begin和end的具體類。我們可以使用單個Tween來整理代碼,用于處理條形圖高度。

import 'package:flutter/material.dart';import 'package:flutter/animation.dart';import 'dart:math';void main() { runApp(new MyApp());}class MyApp extends StatelessWidget { @override Widget build(BuildContext context) {  return new MaterialApp(    title: 'Flutter Demo',    home: new MyHomePage(),  ); }}class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => new _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin { final random = new Random(); int dataSet = 50; AnimationController animation; Tween<double> tween; @override void initState() {  super.initState();  animation = new AnimationController(    duration: const Duration(milliseconds: 300),    vsync: this  );  // Tween({T begin, T end }):創建tween(補間)  tween = new Tween<double>(begin: 0.0, end: dataSet.toDouble());  animation.forward(); } @override void dispose() {  animation.dispose();  super.dispose(); } void changeData() {  setState(() {   dataSet = random.nextInt(100);   tween = new Tween<double>(    /*    @override    T evaluate(     Animation<double> animation    )    返回給定動畫的當前值的內插值    當動畫值分別為0.0或1.0時,此方法返回begin和end     */    begin: tween.evaluate(animation),    end: dataSet.toDouble()   );   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),      /*      Animation<T> animate(       Animation<double> parent      )      返回一個由給定動畫驅動的新動畫,但它承擔由該對象確定的值       */      painter: new BarChartPainter(tween.animate(animation))     )    ),    floatingActionButton: new FloatingActionButton(      onPressed: changeData,      child: new Icon(Icons.refresh),    ),  ); }}class BarChartPainter extends CustomPainter { static const barWidth = 10.0; BarChartPainter(Animation<double> animation)   : animation = animation,    super(repaint: animation); final Animation<double> animation; @override void paint(Canvas canvas, Size size) {  final barHeight = animation.value;  final paint = new Paint()   ..color = Colors.blue[400]   ..style = PaintingStyle.fill;  canvas.drawRect(    new Rect.fromLTWH(      size.width-barWidth/2.0,      size.height-barHeight,      barWidth,      barHeight    ),    paint  ); } @override bool shouldRepaint(BarChartPainter old) => false;}

我們使用Tween將條形高度動畫終點包裝在一個值中,它完全與AnimationController和CustomPainter進行接口,因為Flutter框架現在會在每個動畫時間點上標記CustomPaint進行重繪,而不是將整個MyHomePage子樹標記為重構、重新布局和重繪。這些都是顯示的改進,但是,補間的概念不止如此,它提供了組織我們的想法和代碼的結構。

回到我們的代碼,我們需要一個Bar類型和一個BarTween來動畫化它。我們將與bar相關的類提取到bar.dart文件中,放到main.dart同級目錄下。

import 'package:flutter/material.dart';import 'package:flutter/animation.dart';import 'dart:ui' show lerpDouble;class Bar { Bar(this.height); final double height; static Bar lerp(Bar begin, Bar end, double t) {  return new Bar(lerpDouble(begin.height, end.height, 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 barWidth = 10.0; BarChartPainter(Animation<Bar> animation)   : animation = animation,    super(repaint: animation); final Animation<Bar> animation; @override void paint(Canvas canvas, Size size) {  final bar = animation.value;  final paint = new Paint()   ..color = Colors.blue[400]   ..style = PaintingStyle.fill;  canvas.drawRect(    new Rect.fromLTWH(      size.width-barWidth/2.0,      size.height-bar.height,      barWidth,      bar.height    ),    paint  ); } @override bool shouldRepaint(BarChartPainter old) => false;}


我們遵循FlutterSDK的慣例來定義Bar類的靜態方法BarTween.lerp。DartSDK中沒有double.lerp,所以我們使用dart:ui包中的lerpDouble函數來達到同樣的效果。

現在我們的應用程序可以用條形圖重新顯示。

import 'package:flutter/material.dart';import 'package:flutter/animation.dart';import 'dart:math';import 'bar.dart';void main() { runApp(new MyApp());}class MyApp extends StatelessWidget { @override Widget build(BuildContext context) {  return new MaterialApp(    title: 'Flutter Demo',    home: new MyHomePage(),  ); }}class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => new _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin { final random = new Random(); AnimationController animation; BarTween tween; @override void initState() {  super.initState();  animation = new AnimationController(    duration: const Duration(milliseconds: 300),    vsync: this  );  tween = new BarTween(new Bar(0.0), new Bar(50.0));  animation.forward(); } @override void dispose() {  animation.dispose();  super.dispose(); } void changeData() {  setState(() {   tween = new BarTween(    tween.evaluate(animation),    new Bar(100.0 * random.nextDouble()),   );   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),    ),  ); }}

未完待續。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临海市| 托克逊县| 开鲁县| 温泉县| 安新县| 广东省| 运城市| 安图县| 诸暨市| 宝兴县| 高尔夫| 措勤县| 勐海县| 乐都县| 南阳市| 香港 | 中牟县| 高唐县| 思南县| 乌拉特中旗| 遂溪县| 康乐县| 石景山区| 运城市| 沽源县| 株洲市| 晋中市| 济源市| 达日县| 西华县| 万山特区| 顺义区| 思茅市| 瑞安市| 柳河县| 德令哈市| 天长市| 疏附县| 中卫市| 浮梁县| 德安县|