【移動應(yīng)用開發(fā)技術(shù)】使用Flutter怎么實現(xiàn)動畫效果_第1頁
【移動應(yīng)用開發(fā)技術(shù)】使用Flutter怎么實現(xiàn)動畫效果_第2頁
【移動應(yīng)用開發(fā)技術(shù)】使用Flutter怎么實現(xiàn)動畫效果_第3頁
【移動應(yīng)用開發(fā)技術(shù)】使用Flutter怎么實現(xiàn)動畫效果_第4頁
【移動應(yīng)用開發(fā)技術(shù)】使用Flutter怎么實現(xiàn)動畫效果_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】使用Flutter怎么實現(xiàn)動畫效果

本篇文章為大家展示了使用Flutter怎么實現(xiàn)動畫效果,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。首先,我們需要創(chuàng)建一個新項目myapp,然后把main.dart的內(nèi)容替換成下面的代碼import

'package:flutter/material.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>

{

//

Random([int

seed

]):創(chuàng)建一個隨機(jī)數(shù)生成器

final

random

=

new

Random();

int

dataSet;

void

changeData()

{

setState(()

{

dataSet

=

random.nextInt(100);

});

}

@override

Widget

build(BuildContext

context)

{

return

new

Scaffold(

body:

new

Center(

child:

new

Text('數(shù)據(jù)集:$dataSet'),

),

floatingActionButton:

new

FloatingActionButton(

onPressed:

changeData,

child:

new

Icon(Icons.refresh),

),

);

}

}啟動項目后,應(yīng)用程序會顯示一個居中的文本標(biāo)簽,顯示“數(shù)據(jù)集:null”和浮動按鈕來刷新數(shù)據(jù)。我們的應(yīng)用程序生成的樹結(jié)構(gòu)如下圖所示,您可以看到,雖然控件概念相當(dāng)廣泛,但每個具體的控件類型通常具有非常重要的責(zé)任。通過定義用戶界面的不可變的控件樹,修改用戶界面的唯一方法是重建樹,當(dāng)下一幀到期時告訴Flutter一個子樹所依賴的一些狀態(tài)已經(jīng)改變了。這種狀態(tài)依賴的子樹的根必須是StatefulWidget,一個StatefulWidget不是可變的,但是它的子樹是由State對象構(gòu)建的。Flutter在構(gòu)建期間通過樹重建保留State對象并將其附加到新樹中的各自的控件,然后,它們確定該控件的子樹是如何構(gòu)建的。在我們的應(yīng)用程序中,MyHomePage是以_MyHomePageState為其狀態(tài)的StatefulWidget,每當(dāng)用戶按下按鈕時,我們執(zhí)行一些代碼來更改_MyHomePageState。我們已經(jīng)用setState劃分了這個變化,以便Flutter可以進(jìn)行內(nèi)部管理,并調(diào)度控件樹進(jìn)行重建。當(dāng)發(fā)生這種情況時,_MyHomePageState將構(gòu)建一個稍微不同的子樹,這個子樹以新的MyHomePage實例為根。不可變的控件和狀態(tài)依賴的子樹是Flutter提供的主要工具,用于處理響應(yīng)異步事件(比如按鈕、定時器刻度或輸入數(shù)據(jù))的復(fù)雜用戶界面中的狀態(tài)管理的復(fù)雜性。我們的應(yīng)用程序?qū)⒈3趾唵蔚目丶Y(jié)構(gòu),但我們會做一些動畫定制圖形,第一步是用一個非常簡單的圖表替換每個數(shù)據(jù)集的文本顯示。由于數(shù)據(jù)集當(dāng)前僅有一個在0~100之間數(shù)字,所以圖表將是一個帶有單個條形的條形圖,其高度由該數(shù)字確定,我們將使用初始值50來避免高度為null。import

'package:flutter/material.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>

{

//

Random([int

seed

]):創(chuàng)建一個隨機(jī)數(shù)生成器

final

random

=

new

Random();

int

dataSet

=

50;

void

changeData()

{

setState(()

{

dataSet

=

random.nextInt(100);

});

}

@override

Widget

build(BuildContext

context)

{

return

new

Scaffold(

body:

new

Center(

child:

new

CustomPaint(

size:

new

Size(200.0,

100.0),

painter:

new

BarChartPainter(dataSet.toDouble())

)

),

floatingActionButton:

new

FloatingActionButton(

onPressed:

changeData,

child:

new

Icon(Icons.refresh),

),

);

}

}

//

CustomPaint:是將繪畫委托給CustomPainter策略的控件

class

BarChartPainter

extends

CustomPainter

{

static

const

barWidth

=

10.0;

BarChartPainter(this.barHeight);

final

double

barHeight;

/*

void

paint(

Canvas

canvas,

Size

size

)

當(dāng)對象需要繪制時調(diào)用,它給出Canvas的坐標(biāo)空間,使得原點位于框的左上角,

框的面積是size參數(shù)的大小

*/

@override

void

paint(Canvas

canvas,

Size

size)

{

final

paint

=

new

Paint()

..color

=

Colors.blue[400]

..style

=

PaintingStyle.fill;

//

drawRect:使用給定的Paint繪制一個矩形,是否填充或描邊(或兩者)是由Paint.style控制

canvas.drawRect(

//

Rect.fromLTWH(double

left,

double

top,

double

width,

double

height):

//

從左上角和上邊緣構(gòu)造一個矩形,并設(shè)置其寬度和高度

new

Rect.fromLTWH(

size.width-barWidth/2.0,

size.height-barHeight,

barWidth,

barHeight

),

paint

);

}

/*

bool

shouldRepaint(

CustomPainter,

oldDelegate

)

當(dāng)定制繪畫委托類的新實例被提供給RenderCustomPaint對象時,

或任何時候使用自定義繪畫委托類的新實例創(chuàng)建新的CustomPaint對象

(這相當(dāng)于同一件事,因為后者是以前者實施)

*/

@override

bool

shouldRepaint(BarChartPainter

old)

=>

barHeight

!=

old.barHeight;

}下一步是添加動畫,每當(dāng)數(shù)據(jù)集發(fā)生變化時,我們希望該欄可以平滑而不是突然地改變高度。Flutter有一個AnimationController的概念,用于編排動畫,通過注冊一個監(jiān)聽器,我們被告知當(dāng)動畫值(0.0~1.0)改變時。每當(dāng)發(fā)生這種情況,我們可以像以前一樣調(diào)用setState并更新_MyHomePageState。import

'package:flutter/material.dart';

import

'package:flutter/animation.dart';

import

'dart:math';

import

'dart:ui'

show

lerpDouble;

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

{

//

Random([int

seed

]):創(chuàng)建一個隨機(jī)數(shù)生成器

final

random

=

new

Random();

int

dataSet

=

50;

AnimationController

animation;

double

startHeight;

double

currentHeight;

double

endHeight;

/*

@protected

@mustCallSuper

void

initState()

將此對象插入樹中時調(diào)用

該框架將為其創(chuàng)建的每個State對象精確地調(diào)用此方法一次

*/

@override

void

initState()

{

super.initState();

/*

AnimationController({

double

value,

Duration

duration,

String

debugLabel,

double

lowerBound:

0.0,

double

upperBound:

1.0,

TickerProvider

vsync

})

創(chuàng)建動畫控制器

*/

animation

=

new

AnimationController(

//

這個動畫應(yīng)該持續(xù)的時間長短

duration:

const

Duration(milliseconds:

300),

vsync:

this

)

/*

void

addListener(

VoidCallback

listener

)

每次動畫值更改時調(diào)用監(jiān)聽器

可以使用removeListener刪除監(jiān)聽器

*/

..addListener((){

setState((){

/*

double

lerpDouble(

num

a,

num

b,

double

t

)

在兩個數(shù)字之間進(jìn)行線性內(nèi)插

return

a

+

(b

-

a)

*

t;

*/

currentHeight

=

lerpDouble(

startHeight,

endHeight,

animation.value

);

});

});

startHeight

=

0.0;

currentHeight

=

0.0;

endHeight

=

dataSet.toDouble();

//

開始向前運行這個動畫(朝向最后)

animation.forward();

}

/*

@override

void

dispose()

當(dāng)該對象永久從樹中刪除時調(diào)用

當(dāng)該State對象永遠(yuǎn)不會再次構(gòu)建時,該框架調(diào)用此方法

框架調(diào)用dispose后,該State對象被視為已卸載,并且mounted屬性為false,此時調(diào)用setState是一個錯誤

生命周期的這個階段是終點:沒有辦法重新安裝dispose的State對象

*/

@override

void

dispose()

{

animation.dispose();

super.dispose();

}

void

changeData()

{

setState(()

{

startHeight

=

currentHeight;

dataSet

=

random.nextInt(100);

endHeight

=

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

painter:

new

BarChartPainter(currentHeight)

)

),

floatingActionButton:

new

FloatingActionButton(

onPressed:

changeData,

child:

new

Icon(Icons.refresh),

),

);

}

}

//

CustomPaint:是將繪畫委托給CustomPainter策略的控件

class

BarChartPainter

extends

CustomPainter

{

static

const

barWidth

=

10.0;

BarChartPainter(this.barHeight);

final

double

barHeight;

/*

void

paint(

Canvas

canvas,

Size

size

)

當(dāng)對象需要繪制時調(diào)用,它給出Canvas的坐標(biāo)空間,使得原點位于框的左上角,

框的面積是size參數(shù)的大小

*/

@override

void

paint(Canvas

canvas,

Size

size)

{

final

paint

=

new

Paint()

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論