Flutter使用AnimationController實(shí)現(xiàn)控制動(dòng)畫(huà)
簡(jiǎn)介
之前我們提到了flutter提供了比較簡(jiǎn)單好用的AnimatedContainer和SlideTransition來(lái)進(jìn)行一些簡(jiǎn)單的動(dòng)畫(huà)效果,但是要完全實(shí)現(xiàn)自定義的復(fù)雜的動(dòng)畫(huà)效果,還是要使用AnimationController。
今天我們來(lái)嘗試使用AnimationController來(lái)實(shí)現(xiàn)一個(gè)拖拽圖片,然后返回原點(diǎn)的動(dòng)畫(huà)。
構(gòu)建一個(gè)要?jiǎng)赢?huà)的widget
在本文的例子中,我們希望能夠讓一個(gè)圖片可以實(shí)現(xiàn)拖拽然后自動(dòng)返回原來(lái)位置的效果。
為了實(shí)現(xiàn)這個(gè)功能,我們首先構(gòu)建一個(gè)放在界面中間的圖片。
child: Align( alignment: Alignment.center, child: Card( child: Image(image: AssetImage('images/head.jpg')) ), )
這里使用了Align組件,將一個(gè)圖片對(duì)象放在界面中間。
接下來(lái)我們希望這個(gè)widget可以拖拽,那么把這個(gè)child放到一個(gè)GestureDetector中,這樣就可以相應(yīng)拖拽對(duì)應(yīng)的響應(yīng)。
Widget build(BuildContext context) { final size = MediaQuery.of(context).size; return GestureDetector( onPanUpdate: (details) { setState(() { _animateAlign += Alignment( details.delta.dx / (size.width / 2), details.delta.dy / (size.height / 2), ); }); }, child: Align( alignment: _animateAlign, child: Card( child: widget.child, ), ), ); }
為了能實(shí)現(xiàn)拖動(dòng)的效果,我們需要在GestureDetector的onPanUpdate方法中對(duì)Align的位置進(jìn)行修改,所以我們需要調(diào)用setState方法。
在setState方法中,我們根據(jù)手勢(shì)的位置來(lái)調(diào)整Alignment的位置,所以這里需要用到MediaQuery來(lái)獲取屏幕的大小。
但是現(xiàn)在實(shí)現(xiàn)的效果是圖像隨手勢(shì)移動(dòng)而移動(dòng),我們還需要實(shí)現(xiàn)在手放開(kāi)之后,圖像自動(dòng)回復(fù)到原來(lái)位置的動(dòng)畫(huà)效果。
讓圖像動(dòng)起來(lái)
因?yàn)檫@次需要變動(dòng)的是Alignment,所以我們先定義一個(gè)包含Alignment的Animation屬性:
late Animation<Alignment> _animation;
接下來(lái)我們需要定義一個(gè)AnimationController,用來(lái)控制動(dòng)畫(huà)信息,并且指定我們需要的動(dòng)畫(huà)起點(diǎn)和終點(diǎn):
late AnimationController _controller; _animation = _controller.drive( AlignmentTween( begin: _animateAlign, end: Alignment.center, ), );
我們動(dòng)畫(huà)的起點(diǎn)位置就是當(dāng)前image所在的Alignment,終點(diǎn)就在Alignment.center。
Alignment有一個(gè)專門表示位置信息的類叫做AlignmentTween,如上代碼所示。
有了起點(diǎn)和終點(diǎn), 我們還需要指定從起點(diǎn)移動(dòng)到終點(diǎn)的方式,這里模擬使用彈簧效果,所以使用SpringSimulation。
SpringSimulation需要提供對(duì)spring的描述,起點(diǎn)距離,結(jié)束距離和初始速度。
const spring = SpringDescription( mass: 30, stiffness: 1, damping: 1, ); final simulation = SpringSimulation(spring, 0, 1, -1);
我們使用上面創(chuàng)建的simulation,來(lái)實(shí)現(xiàn)動(dòng)畫(huà):
_controller.animateWith(simulation);
最后我們需要在手勢(shì)結(jié)束的時(shí)候來(lái)執(zhí)行這個(gè)動(dòng)畫(huà)即可:
onPanEnd: (details) { _runAnimation(); },
最后,運(yùn)行效果如下所示:
總結(jié)
AnimationController是一個(gè)很強(qiáng)大的組件,但是使用起來(lái)也不是那么的復(fù)雜, 我們只需要定義好起點(diǎn)和終點(diǎn),然后指定動(dòng)畫(huà)效果即可。
本文的例子:github.com/ddean2009/learn-flutter
以上就是Flutter使用AnimationController實(shí)現(xiàn)控制動(dòng)畫(huà)的詳細(xì)內(nèi)容,更多關(guān)于Flutter AnimationController的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android中沒(méi)有插入SD情況下的文件寫(xiě)入和讀取方法
在Android開(kāi)發(fā)時(shí)會(huì)遇到如下一種場(chǎng)合希望應(yīng)用下載到當(dāng)前應(yīng)用的根目錄下,而非SD卡中然后可以隨時(shí)被該應(yīng)用或其他應(yīng)用訪問(wèn)這個(gè)文件,即具有被全局讀取的權(quán)限2012-11-11android?scrollview頂部漸漸消失實(shí)現(xiàn)實(shí)例詳解
這篇文章主要為大家介紹了android?scrollview頂部漸漸消失實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11Kotlin協(xié)程開(kāi)發(fā)之Flow的融合與Channel容量及溢出策略介紹
這篇文章主要介紹了Kotlin協(xié)程:Flow的融合、Channel容量、溢出策略,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09Android實(shí)現(xiàn)網(wǎng)易新聞客戶端首頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)易新聞客戶端首頁(yè)效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11MTK Android平臺(tái)開(kāi)發(fā)流程
這篇文章主要介紹了MTK在Android平臺(tái)開(kāi)發(fā)的流程,一共分析了44個(gè)步驟,需要的朋友學(xué)習(xí)下吧。2017-12-12Flutter利用注解生成可自定義的路由的實(shí)現(xiàn)
這篇文章主要介紹了Flutter利用注解生成可自定義的路由的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08