利用Flutter實(shí)現(xiàn)“孔雀開(kāi)屏”的動(dòng)畫(huà)效果
前言
今天分享一個(gè)類似“孔雀開(kāi)屏”的動(dòng)畫(huà)效果,打開(kāi)新的頁(yè)面時(shí),新的頁(yè)面從屏幕右上角以圓形逐漸打開(kāi)到全屏。
先來(lái)看下具體的效果
不知道這種效果大家叫什么名字?如果有更合適的名字可以在評(píng)論處告訴我,下面來(lái)說(shuō)下如何實(shí)現(xiàn)此效果。
在使用Navigator進(jìn)入一個(gè)新的頁(yè)面時(shí),通常用法如下:
Navigator.of(context).push(MaterialPageRoute( builder: (context){ return PageB(); } ));
MaterialPageRoute就包含了切換頁(yè)面時(shí)的動(dòng)畫(huà)效果,在iOS上效果是左右滑動(dòng)切換,在Android上效果是上下滑動(dòng),如果想要自定義切換效果如何實(shí)現(xiàn)呢?答案是使用PageRouteBuilder,用法如下:
Navigator.of(context).push(PageRouteBuilder(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { ... }));
在pageBuilder函數(shù)中使用animation返回新頁(yè)面的動(dòng)畫(huà)效果即可。
新的頁(yè)面以圓形效果逐漸打開(kāi),注意并沒(méi)有縮放效果,所以新的頁(yè)面是被裁減的,新的頁(yè)面以右上角為圓心,半徑逐漸變大進(jìn)行裁切,就是我們想要的效果。
通過(guò)上面的分析,使用ClipPath對(duì)新的頁(yè)面進(jìn)行裁切
Navigator.of(context).push(PageRouteBuilder(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { return AnimatedBuilder( animation: animation, builder: (context, child) { return ClipPath( clipper: CirclePath(animation.value), child: child, ); }, child: PageB(), ); }));
重點(diǎn)是CirclePath,這就是裁切的路徑,
class CirclePath extends CustomClipper<Path> { CirclePath(this.value); final double value; @override Path getClip(Size size) { var path = Path(); double radius = value * sqrt(size.height * size.height + size.width * size.width); path.addOval(Rect.fromLTRB( size.width - radius, -radius, size.width + radius, radius)); return path; } @override bool shouldReclip(CustomClipper<Path> oldClipper) { return true; } }
由于Path沒(méi)有直接添加圓形的API函數(shù),因此使用橢圓方法,只需將橢圓的矩形區(qū)域設(shè)置為正方形,那么裁切出來(lái)的就是圓形。
半徑的最大值并不是屏幕的寬或者高,而是屏幕的對(duì)角線長(zhǎng)度。
由于是從右上角開(kāi)始,而且裁切的矩形區(qū)域必須是正方形,所以裁切的矩形區(qū)域是超出頁(yè)面區(qū)域的。
如果很多頁(yè)面都用到了這個(gè)效果,可以進(jìn)行封裝,類似于MaterialPageRoute,封裝如下:
class CirclePageRoute extends PageRoute { CirclePageRoute({ @required this.builder, this.transitionDuration = const Duration(milliseconds: 500), this.opaque = true, this.barrierDismissible = false, this.barrierColor, this.barrierLabel, this.maintainState = true, }); final WidgetBuilder builder; @override final Duration transitionDuration; @override final bool opaque; @override final bool barrierDismissible; @override final Color barrierColor; @override final String barrierLabel; @override final bool maintainState; @override Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { return AnimatedBuilder( animation: animation, builder: (context, child) { return ClipPath( clipper: CirclePath(animation.value), child: child, ); }, child: builder(context), ); } }
使用
Navigator.of(context).push(CirclePageRoute(builder: (context) { return PageB(); }));
如果你查看CupertinoPageRoute、MaterialPageRoute、PageRouteBuilder的源碼,你會(huì)發(fā)現(xiàn)這3個(gè)都是繼承自PageRoute,所以,不知不覺(jué)我們又學(xué)會(huì)了自定義路由。
總結(jié)
到此這篇關(guān)于利用Flutter實(shí)現(xiàn)“孔雀開(kāi)屏”的動(dòng)畫(huà)效果的文章就介紹到這了,更多相關(guān)Flutter動(dòng)畫(huà)效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- flutter實(shí)現(xiàn)帶刪除動(dòng)畫(huà)的listview功能
- Flutter實(shí)戰(zhàn)教程之酷炫的開(kāi)關(guān)動(dòng)畫(huà)效果
- 如何使用Flutter實(shí)現(xiàn)58同城中的加載動(dòng)畫(huà)詳解
- flutter RotationTransition實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫(huà)
- flutter PositionedTransition實(shí)現(xiàn)縮放動(dòng)畫(huà)
- flutter FadeTransition實(shí)現(xiàn)透明度漸變動(dòng)畫(huà)
- Flutter路由的跳轉(zhuǎn)、動(dòng)畫(huà)和傳參詳解(最簡(jiǎn)單)
- Flutter 用自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)實(shí)現(xiàn)頁(yè)面切換
相關(guān)文章
Android自動(dòng)化測(cè)試處理各種彈窗的操作方法
這篇文章主要介紹了Android自動(dòng)化測(cè)試中如何處理各種彈窗,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07Android實(shí)現(xiàn)3D層疊式卡片圖片展示
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)3D層疊式卡片圖片展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10Android Gradle Plug 4.1.0 升級(jí)后gradle獲取manifest位置失敗問(wèn)題解決
這篇文章主要介紹了Android Gradle Plug 4.1.0 升級(jí)后gradle獲取manifest位置失敗問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Android仿微信頁(yè)面底部導(dǎo)航效果代碼實(shí)現(xiàn)
本文給大家分享一段代碼有關(guān)android仿微信頁(yè)面底部導(dǎo)航效果代碼實(shí)現(xiàn)的思路,非常不錯(cuò),感興趣的朋友一起看看吧2016-09-09Android開(kāi)發(fā)Kotlin語(yǔ)言協(xié)程的依賴及使用示例
這篇文章主要為大家介紹了Android開(kāi)發(fā)Kotlin語(yǔ)言協(xié)程的依賴及使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Android TextView字體顏色設(shè)置方法小結(jié)
這篇文章主要介紹了Android TextView字體顏色設(shè)置方法,結(jié)合實(shí)例形式總結(jié)分析了Android開(kāi)發(fā)中TextView設(shè)置字體顏色的常用技巧,需要的朋友可以參考下2016-02-02Android中常用的三個(gè)Dialog彈窗總結(jié)解析
自己雖然一直使用過(guò)dialog,但是一直都是復(fù)制、粘貼;不清楚dialog的具體用途,這次趁著有時(shí)間,總結(jié)一下具體用法,感興趣的朋友跟著小編來(lái)看看吧2021-10-10Android開(kāi)發(fā)實(shí)現(xiàn)NFC刷卡讀取的兩種方式
這篇文章主要為大家詳細(xì)介紹了Android開(kāi)發(fā)中實(shí)現(xiàn)NFC刷卡讀取的兩種方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Android 打開(kāi)網(wǎng)絡(luò)上pdf文件
本文主要介紹了Android打開(kāi)網(wǎng)絡(luò)上pdf文件的方法,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04