Android利用Hero實(shí)現(xiàn)列表與詳情頁(yè)無(wú)縫切換動(dòng)畫
前言
介紹了幾篇 Hero 動(dòng)畫,我們來(lái)一個(gè) Hero 動(dòng)畫應(yīng)用案例。在一些應(yīng)用中,列表的元素和詳情的內(nèi)容是一致的,這個(gè)時(shí)候利用 Hero 動(dòng)畫切換到詳情會(huì)感覺無(wú)縫過(guò)渡,用戶體驗(yàn)會(huì)更好。例如本篇我們要實(shí)現(xiàn)下面的效果:

Hero 應(yīng)用:列表與詳情切換
思路
上面的效果是列表和詳情共用了頭像和頭像的背景色。二者的組合是一個(gè) Stack 組件,因此可以使用 Hero 組件完成。然后是 Hero 組件的移動(dòng),我們先做了水平移動(dòng),再做垂直方向移動(dòng),這樣過(guò)渡體驗(yàn)會(huì)更好,這種可以用我們自定義的 RectTween 完成。下面是我們的各個(gè)部分的實(shí)現(xiàn)過(guò)程。
列表元素
列表元素我們定義一個(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ú)抽出來(lái)一個(gè) ListImage 組件。整個(gè)頭像是一個(gè) Stack 組件,然后底部的背景 Container 右邊的圓弧是通過(guò) 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)過(guò)來(lái)是個(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ì)。后來(lái)百度了一下,發(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 來(lái)設(shè)置。
源碼
完整源碼已經(jīng)上傳至:動(dòng)畫相關(guān)代碼,代碼在 lib/hero/list_to_detail_hero.dart 中。
總結(jié)
本篇介紹了一個(gè) Hero 組件的實(shí)際應(yīng)用場(chǎng)景 —— 列表到詳情之間利用 Hero 過(guò)渡切換。實(shí)際上,如果考慮更好的動(dòng)畫效果,還可以結(jié)合 AnimatedWidget,AnimatedBuilder 等配合完成。
以上就是Android利用Hero實(shí)現(xiàn)列表與詳情頁(yè)無(wú)縫切換動(dòng)畫的詳細(xì)內(nèi)容,更多關(guān)于Android Hero無(wú)縫切換動(dòng)畫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android webview與js的數(shù)據(jù)交互
有了WebView這個(gè)組件,Android應(yīng)用開發(fā)技術(shù)也就轉(zhuǎn)嫁到html與java數(shù)據(jù)交互上來(lái)。說(shuō)白了就是js與WebView的數(shù)據(jù)交互,這就是本文所要討論的2017-04-04
Android實(shí)現(xiàn)LED發(fā)光字效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)LED發(fā)光字效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
android自定義View實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
這篇文章主要為大家詳細(xì)介紹了android自定義View實(shí)現(xiàn)簡(jiǎn)單五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android實(shí)現(xiàn)商城購(gòu)物車功能的實(shí)例代碼
最近公司項(xiàng)目做商城模塊,需要實(shí)現(xiàn)購(gòu)物車功能,主要實(shí)現(xiàn)了單選、全選,金額合計(jì),商品刪除,商品數(shù)量加減等功能,這篇文章主要介紹了Android實(shí)現(xiàn)商城購(gòu)物車功能,需要的朋友可以參考下2019-06-06
Android實(shí)現(xiàn)自動(dòng)截圖腳本
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)自動(dòng)截圖腳本,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Android實(shí)現(xiàn)用代碼簡(jiǎn)單安裝和卸載APK的方法
這篇文章主要介紹了Android實(shí)現(xiàn)用代碼簡(jiǎn)單安裝和卸載APK的方法,涉及Android針對(duì)APK文件及package的相關(guān)操作技巧,需要的朋友可以參考下2016-08-08
Flutter 封裝一個(gè) Banner 輪播圖效果的實(shí)例代碼
這篇文章主要介紹了Flutter 封裝一個(gè) Banner 輪播圖效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
Android自定義VIew實(shí)現(xiàn)衛(wèi)星菜單效果淺析
這篇文章主要介紹了Android自定義VIew實(shí)現(xiàn)衛(wèi)星菜單效果淺析,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11

