




版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 科技創(chuàng)新引領(lǐng)下的文化產(chǎn)業(yè)發(fā)展趨勢分析
- 廠房維修安全合同范本
- 廠房包租意向合同范本
- 買賣荒山合同范本
- 交換旅游住房合同范本
- 口腔店內(nèi)合同范本
- 租場地訂金合同范本
- 合作合同范例保密協(xié)議
- 乙方簽字合同范本模板
- 住建部勘察合同范本
- 聲門下分泌物引流的應(yīng)用專家講座
- 硝酸脂類藥物的作用注意事項不良反應(yīng)
- 科普版小學(xué)英語六年級下冊全冊教案
- 腦梗合并心衰護(hù)理查房
- 婦聯(lián)普法知識競賽參考試題庫300題(含答案)
- 最全全國各省市縣名稱
- 溶液鍍膜法完整版本
- 消化道出血應(yīng)急預(yù)案
- 【溫州眼鏡出口遭遇技術(shù)貿(mào)易壁壘的現(xiàn)狀及對策(定量論文)15000字】
- 2024年《滕王閣序》原文及翻譯
- 文華財經(jīng)“麥語言”函數(shù)手冊
評論
0/150
提交評論