欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter進(jìn)階之實現(xiàn)動畫效果(二)

 更新時間:2018年08月18日 16:46:25   作者:何小有  
這篇文章主要為大家詳細(xì)介紹了Flutter進(jìn)階之實現(xiàn)動畫效果的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

在上一篇文章:Flutter進(jìn)階—實現(xiàn)動畫效果(一)的最后,我們說到需要一個處理程序混亂的概念。在這一篇文章中,我們會引入補間,它是構(gòu)建動畫代碼的一個非常簡單的概念,主要作用是用面向?qū)ο蟮姆椒ㄌ娲懊嫦蜻^程的方法。tween是一個值,它描述了其他值的空間中的兩個點之間的路徑,比如條形圖的動畫值從0運行到1。

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

abstract class Tween<T> {
 final T begin;
 final T end;

 Tween(this.begin, this.end);

 T lerp(double t);
}

術(shù)語lerp來自計算機圖形學(xué)領(lǐng)域,是線性插值(作為名詞)和線性內(nèi)插(作為動詞)的縮寫。參數(shù)t是動畫值,補間應(yīng)該從begin(當(dāng)t為0時)到end(當(dāng)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 }):創(chuàng)建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
    )
    返回給定動畫的當(dāng)前值的內(nèi)插值
    當(dāng)動畫值分別為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
      )
      返回一個由給定動畫驅(qū)動的新動畫,但它承擔(dān)由該對象確定的值
       */
      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進(jìn)行接口,因為Flutter框架現(xiàn)在會在每個動畫時間點上標(biāo)記CustomPaint進(jìn)行重繪,而不是將整個MyHomePage子樹標(biāo)記為重構(gòu)、重新布局和重繪。這些都是顯示的改進(jìn),但是,補間的概念不止如此,它提供了組織我們的想法和代碼的結(jié)構(gòu)。

回到我們的代碼,我們需要一個Bar類型和一個BarTween來動畫化它。我們將與bar相關(guān)的類提取到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類的靜態(tài)方法BarTween.lerp。DartSDK中沒有double.lerp,所以我們使用dart:ui包中的lerpDouble函數(shù)來達(dá)到同樣的效果。

現(xiàn)在我們的應(yīng)用程序可以用條形圖重新顯示。

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

未完待續(xù)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論