Android利用Hero實(shí)現(xiàn)列表與詳情頁(yè)無縫切換動(dòng)畫
前言
介紹了幾篇 Hero
動(dòng)畫,我們來一個(gè) Hero
動(dòng)畫應(yīng)用案例。在一些應(yīng)用中,列表的元素和詳情的內(nèi)容是一致的,這個(gè)時(shí)候利用 Hero
動(dòng)畫切換到詳情會(huì)感覺無縫過渡,用戶體驗(yàn)會(huì)更好。例如本篇我們要實(shí)現(xiàn)下面的效果:
Hero 應(yīng)用:列表與詳情切換
思路
上面的效果是列表和詳情共用了頭像和頭像的背景色。二者的組合是一個(gè) Stack
組件,因此可以使用 Hero
組件完成。然后是 Hero
組件的移動(dòng),我們先做了水平移動(dòng),再做垂直方向移動(dòng),這樣過渡體驗(yàn)會(huì)更好,這種可以用我們自定義的 RectTween
完成。下面是我們的各個(gè)部分的實(shí)現(xiàn)過程。
列表元素
列表元素我們定義一個(gè) HeroListItem
類,整個(gè)列表元素需要點(diǎn)擊進(jìn)入詳情,使用 GestureDetector
包裹。然后使用 Row
組件完成橫向布局,而頭像部分使用的是 Stack
組件。HeroListItem
的 build
方法如下:
Widget?build(BuildContext?context)?{ ??return?GestureDetector( ????child:?Container( ??????padding:?EdgeInsets.fromLTRB(0,?10.0,?10.0,?10.0), ??????child:?Row( ????????children:?[ ??????????Hero( ????????????tag:?heroTag, ????????????createRectTween:?(begin,?end)?{ ??????????????return?ListToDetailRectTween( ????????????????begin:?begin!, ????????????????end:?end!, ??????????????); ????????????}, ????????????child:?ListImage( ??????????????assetImageName:?assetImageName, ??????????????imageBgColor:?imageBgColor, ????????????), ??????????), ??????????SizedBox( ????????????width:?10.0, ??????????), ??????????Expanded( ????????????child:?Text( ??????????????content, ??????????????style:?TextStyle( ????????????????color:?Colors.black87, ????????????????fontSize:?18.0, ??????????????), ??????????????maxLines:?2, ????????????), ??????????), ????????], ??????), ????), ????onTap:?()?{ ??????Navigator.of(context).push( ????????MaterialPageRoute( ??????????fullscreenDialog:?true, ??????????builder:?(context)?=>?ListDetail( ????????????heroTag:?heroTag, ????????????imageBgColor:?imageBgColor, ????????????assetImageName:?assetImageName, ??????????), ????????), ??????); ????}, ??); }
頭像這塊因?yàn)樯婕暗奖尘暗倪吙驁A弧處理,單獨(dú)抽出來一個(gè) ListImage
組件。整個(gè)頭像是一個(gè) Stack 組件,然后底部的背景 Container
右邊的圓弧是通過 BoxDecoration
完成的。后面的 OvalImage
是一個(gè)圓形圖片包裝類,其實(shí)就是拿 ClipOval
包裹住 Image
組件就可以了,這里就不貼代碼了。
Widget?build(BuildContext?context)?{ ??return?Stack( ????children:?[ ??????Container( ????????height:?90.0, ????????width:?110, ????????decoration:?BoxDecoration( ??????????color:?imageBgColor, ??????????borderRadius:?BorderRadius.only( ????????????topRight:?Radius.circular(45.0), ????????????bottomRight:?Radius.circular(45.0), ??????????), ????????), ??????), ??????Positioned( ????????child:?OvalImage( ??????????assetImageName:?assetImageName, ??????????imageSize:?90.0, ????????), ????????left:?20.0, ????????top:?0.0, ??????) ????], ??); }
列表這里的關(guān)鍵其實(shí)就是使用 Hero
將頭像區(qū)域包裹,然后使用了 createRectTween
定義了 Hero
飛行路徑。
詳情頁(yè)面
詳情頁(yè)面因?yàn)樘D(zhuǎn)過來是個(gè)全屏彈窗的方式,因此需要自己完成返回按鈕的操作。實(shí)際上詳情頁(yè)頂部就是一個(gè) Stack
組件,組件的背景色和圖片和列表保持一樣,再在 Stack
組件加上關(guān)閉按鈕和詳情標(biāo)題即可。這里為了保持頁(yè)面頂部覆蓋狀態(tài)欄,使用的是 CustomScrollView
實(shí)現(xiàn) (關(guān)于 CustomScrollView
可以看這篇:Flutter 實(shí)現(xiàn)更有趣的頁(yè)面滾動(dòng)效果)。頂部的界面我們定義了一個(gè) ListDetailHeader 組件,代碼如下所示。
class?ListDetailHeader?extends?StatelessWidget?{ ??final?heroTag; ??final?imageBgColor; ??final?assetImageName; ??const?ListDetailHeader({ ????Key??key, ????required?this.heroTag, ????required?this.imageBgColor, ????required?this.assetImageName, ??})?:?super(key:?key); ??@override ??Widget?build(BuildContext?context)?{ ????return?Hero( ??????child:?Stack( ????????children:?[ ??????????Container( ????????????height:?160.0, ????????????width:?double.infinity, ????????????decoration:?BoxDecoration( ??????????????color:?imageBgColor, ????????????), ??????????), ??????????Positioned( ????????????child:?Material( ??????????????child:?IconButton( ????????????????icon:?Icon( ??????????????????Icons.close, ??????????????????color:?Colors.white, ????????????????), ????????????????onPressed:?()?{ ??????????????????Navigator.of(context).pop(); ????????????????}, ??????????????), ??????????????color:?Colors.transparent, ????????????), ????????????left:?10.0, ????????????top:?50.0, ????????????height:?40.0, ??????????), ??????????Positioned( ????????????child:?OvalImage( ??????????????assetImageName:?assetImageName, ??????????????imageSize:?90.0, ????????????), ????????????right:?20.0, ????????????top:?50.0, ??????????), ??????????Positioned( ????????????child:?Material( ??????????????color:?Colors.transparent, ??????????????child:?Text( ????????????????'這是詳情', ????????????????style:?TextStyle( ??????????????????color:?Colors.white, ??????????????????fontSize:?18.0, ????????????????), ????????????????maxLines:?1, ??????????????), ????????????), ????????????left:?20, ????????????top:?100, ??????????), ????????], ??????), ??????tag:?heroTag, ??????createRectTween:?(begin,?end)?{ ????????return?ListToDetailRectTween( ??????????begin:?begin!, ??????????end:?end!, ????????); ??????}, ????); ??} }
這里沒什么特別的,但是一開始遇到了一個(gè)問題就是發(fā)現(xiàn)文本下面會(huì)有兩條下劃線,而且樣式也不對(duì)。后來百度了一下,發(fā)現(xiàn)是因?yàn)槭褂?nbsp;fullscreenDialog
的時(shí)候,實(shí)際上是使用的蘋果風(fēng)格的頁(yè)面,要保持 Material
風(fēng)格的話,需要使用 Scaffold
或者使用 Material
組件包裹。因此,在 Text
組件上一層加了一個(gè) Material
組件。Material
組件本身的背景色是白色的,為了不影響組件的底色,需要設(shè)置它的背景色為transparent
。
不被 Material 包裹文本
這里的 Hero
組件的 tag
和 createRectTween
和列表保持一致即可,實(shí)際的 tag
可以使用列表元素的 id
來設(shè)置。
源碼
完整源碼已經(jīng)上傳至:動(dòng)畫相關(guān)代碼,代碼在 lib/hero/list_to_detail_hero.dart
中。
總結(jié)
本篇介紹了一個(gè) Hero 組件的實(shí)際應(yīng)用場(chǎng)景 —— 列表到詳情之間利用 Hero
過渡切換。實(shí)際上,如果考慮更好的動(dòng)畫效果,還可以結(jié)合 AnimatedWidget
,AnimatedBuilder
等配合完成。
以上就是Android利用Hero實(shí)現(xiàn)列表與詳情頁(yè)無縫切換動(dòng)畫的詳細(xì)內(nèi)容,更多關(guān)于Android Hero無縫切換動(dòng)畫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android string-array數(shù)據(jù)源簡(jiǎn)單使用
這篇文章主要介紹了Android string-array數(shù)據(jù)源簡(jiǎn)單使用的相關(guān)資料,需要的朋友可以參考下2016-09-09判斷Android程序是否在前臺(tái)運(yùn)行的兩種方法
這篇文章主要介紹了判斷Android程序是否在前臺(tái)運(yùn)行的兩種方法,本文直接給出實(shí)現(xiàn)代碼,,需要的朋友可以參考下2015-06-06Android實(shí)現(xiàn)動(dòng)畫效果詳解
這篇文章主要介紹了Android實(shí)現(xiàn)動(dòng)畫效果詳解,目前Android平臺(tái)提供了Tween動(dòng)畫和Frame動(dòng)畫,實(shí)現(xiàn)這兩類動(dòng)畫有兩種方式:一種使用XML文件(文件放在res/anim),一種直接代碼搞定,需要的朋友可以參考下2015-07-07Android PopupWindow被輸入法彈上去之后無法恢復(fù)原位的解決辦法
這篇文章主要介紹了Android PopupWindow被輸入法彈上去之后無法恢復(fù)原位的解決辦法,需要的朋友可以參考下2016-12-12Android?SharedPreferences性能瓶頸解析
這篇文章主要為大家介紹了Android?SharedPreferences性能瓶頸解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Android viewpage實(shí)現(xiàn)可控制的禁止滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android viewpage實(shí)現(xiàn)可控制的禁止滑動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11Android懸浮窗屏蔽懸浮窗外部所有的點(diǎn)擊事件的實(shí)例代碼
這篇文章主要介紹了Android懸浮窗屏蔽懸浮窗外部所有的點(diǎn)擊事件實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03