介紹
在本教程中,我們將會通過一個簡單的樣例,學習如何基于ArkTS的聲明式開發范式開發轉場動畫。其中包含頁面間轉場、組件內轉場以及共享元素轉場。效果如圖所示:
說明: 本Codelab使用的display接口處于mock階段,在預覽器上使用會顯示白屏現象,可選擇在真機或模擬器上運行。
相關概念
- [頁面間轉場]:頁面轉場通過在全局pageTransition方法內配置頁面入場組件和頁面退場組件來自定義頁面轉場動效。
- [組件內轉場]:組件轉場主要通過transition屬性進行配置轉場參數,在組件插入和刪除時進行過渡動效,主要用于容器組件子組件插入刪除時提升用戶體驗(需要配合animateTo才能生效,動效時長、曲線、延時跟隨animateTo中的配置)。
- [共享元素轉場]:通過修改共享元素的sharedTransition屬性設置元素在不同頁面之間過渡動效。例如,如果兩個頁面使用相同的圖片(但位置和大小不同),圖片就會在這兩個頁面之間流暢地平移和縮放。
環境搭建
軟件要求
- [DevEco Studio]版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 開發板類型:[潤和RK3568開發板]。
- OpenHarmony系統:3.2 Release。
環境搭建
完成本篇Codelab我們首先要完成開發環境的搭建,本示例以RK3568開發板為例,參照以下步驟進行:
- [獲取OpenHarmony系統版本]:標準系統解決方案(二進制)。以3.2 Release版本為例:
- 搭建燒錄環境。
- [完成DevEco Device Tool的安裝]
- [完成RK3568開發板的燒錄]
- 搭建開發環境。
代碼結構解讀
本篇Codelab只對核心代碼進行講解,完整代碼可以直接從gitee獲取。
├──entry/src/main/ets // 代碼區
│ ├──common
│ │ ├──constants
│ │ │ └──CommonConstants.ets // 公共常量類
│ │ └──utils
│ │ ├──DimensionUtil.ets // 屏幕適配工具類
│ │ └──GlobalContext.ets // 全局上下文工具類
│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口類
│ ├──pages
│ │ ├──BottomTransition.ets // 底部滑出頁面
│ │ ├──ComponentTransition.ets // 移動動畫轉場頁面
│ │ ├──CustomTransition.ets // 放縮動畫轉場頁面
│ │ ├──FullCustomTransition.ets // 旋轉動畫轉場頁面
│ │ ├──Index.ets // 應用首頁
│ │ ├──ShareItem.ets // 共享元素轉場部件
│ │ └──SharePage.ets // 共享元素轉場頁面
│ ├──view
│ │ ├──BackContainer.ets // 自定義頭部返回組件
│ │ └──TransitionElement.ets // 自定義動畫元素
│ └──viewmodel
│ └──AnimationModel.ets // 動畫封裝的model類
└──entry/src/main/resources // 資源文件目錄
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
構建主界面
在這個任務中,我們將完成主界面的設計和開發,效果如圖所示:
從上面效果圖可以看出,主界面主要由5個相同樣式的功能菜單組成,我們可以將這些菜單抽取成一個子組件Item。
- 將所需要的圖片添加到resources > base > media目錄下。
- 在Index.ets中引入首頁所需要圖片和路由信息,聲明子組件的UI布局并添加樣式,使用ForEach方法循環渲染首頁列表常量數據“INDEX_ANIMATION_MODE”,其中imgRes是設置按鈕的背景圖片,url用于設置頁面路由的地址。
// Index.ets import { INDEX_ANIMATION_MODE } from '../common/constants/CommonConstants'; Column() { ForEach(INDEX_ANIMATION_MODE, (item: AnimationModel) = > { Row() .backgroundImage(item.imgRes) .backgroundImageSize(ImageSize.Cover) .backgroundColor($r('app.color.trans_parent')) .height(DimensionUtil.getVp($r('app.float.main_page_body_height'))) .margin({ bottom: DimensionUtil.getVp($r('app.float.main_page_body_margin')) }) .width(FULL_LENGTH) .borderRadius(BORDER_RADIUS) .onClick(() = > { router.pushUrl({ url: item.url }) .catch((err: Error) = > { hilog.error(DOMAIN, PREFIX, FORMAT, err); }); }) }, (item: AnimationModel) = > JSON.stringify(item)) }
頁面間轉場
實現“底部滑入”效果
在BottomTransition申明pageTransition方法配置轉場參數,其中PageTransitionEnter用于自定義當前頁面的入場效果,PageTransitionExit用于自定義當前頁面的退場效果。效果如圖所示:
通過設置PageTransitionEnter和PageTransitionExit的slide屬性為SlideEffect.Bottom,來實現BottomTransition入場時從底部滑入,退場時從底部滑出。
// BottomTransition.ets
@Entry
@Component
struct BottomTransition {
build() {
Column() {
TransitionElement()
}
}
/**
* 頁面轉場通過全局pageTransition方法進行配置轉場參數
*
* SlideEffect.Bottom 入場時從屏幕下方滑入。
* SlideEffect.Bottom 退場時從屏幕下方滑出。
*/
pageTransition() {
PageTransitionEnter({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
PageTransitionExit({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
}
}
實現”頁面轉場:自定義1“效果
本節實現的效果,頁面入場時為淡入和放大,退場時從右下角滑出。效果如圖所示:
在CustomTransition.ets的Column組件中添加TransitionElement組件,并且定義pageTransition方法。
// CustomTransition.ets
@Entry
@Component
struct CustomTransition {
build() {
Column() {
TransitionElement()
}
}
/**
* 頁面轉場通過全局pageTransition方法進行配置轉場參數
*
* 進場時透明度設置從0.2到1;x、y軸縮放從0變化到1
* 退場時x、y軸的偏移量為500
*/
pageTransition() {
PageTransitionEnter({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth })
.opacity(CUSTOM_TRANSITION_OPACITY)
.scale(CUSTOM_TRANSITION_SCALE)
PageTransitionExit({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth })
.translate(CUSTOM_TRANSITION_TRANSLATE)
}
}
說明: translate設置頁面轉場時的平移效果,為入場時起點和退場時終點的值,和slide同時設置時默認生效slide。
實現”頁面轉場:自定義2“動效
本節實現的效果,頁面入場時淡入和放大,同時順時針旋轉;退場時淡出和縮小,同時逆時針旋轉。效果如圖所示:
在FullCustomTransition.ets的Column組件中添加TransitionElement組件,并且定義pageTransition方法。給Stack組件添加opacity、scale、rotate屬性,定義變量animValue用來控制Stack組件的動效,在PageTransitionEnter和PageTransitionExit組件中動態改變myProgress的值。
// FullCustomTransition.ets
@Entry
@Component
struct FullCustomTransition {
@State animValue: number = FULL_CUSTOM_TRANSITION_DEFAULT_ANIM_VALUE;
build() {
Column() {
TransitionElement()
}
.opacity(this.animValue)
.scale({ x: this.animValue, y: this.animValue })
.rotate({
z: FULL_CUSTOM_TRANSITION_ROTATE_Z,
angle: FULL_CUSTOM_TRANSITION_ANGLE * this.animValue
})
}
/**
* 頁面轉場通過全局pageTransition方法進行配置轉場參數
*
* 進場過程中會逐幀觸發onEnter回調,入參為動效的歸一化進度(0 - 1)
* 進場過程中會逐幀觸發onExit回調,入參為動效的歸一化進度(0 - 1)
*/
pageTransition() {
PageTransitionEnter({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth })
.onEnter((type?: RouteType, progress?: number) = > {
if (!progress) {
return;
}
this.animValue = progress;
});
PageTransitionExit({ duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth })
.onExit((type?: RouteType, progress?: number) = > {
if (!progress) {
return;
}
this.animValue = FULL_CUSTOM_TRANSITION_DEFAULT_ANIM_VALUE - progress;
});
}
}
組件內轉場
本節實現組件內轉場動效,通過一個按鈕來控制組件的添加和移除,呈現容器組件子組件添加和移除時的動效。效果如圖所示:
組件轉場主要通過transition屬性方法配置轉場參數,在組件添加和移除時會執行過渡動效,需要配合animateTo才能生效。動效時長、曲線、延時跟隨animateTo中的配置。
- 在ComponentTransition.ets文件中,新建Image子組件,并添加兩個transition屬性,分別用于定義組件的添加動效和移除動效。
// ComponentTransition.ets Image($r('app.media.bg_element')) .TransitionEleStyles() .transition({ type: TransitionType.Insert, scale: COMPONENT_TRANSITION_SCALE, opacity: COMPONENT_TRANSITION_OPACITY }) .transition({ type: TransitionType.Delete, rotate: COMPONENT_TRANSITION_ROTATE, opacity: COMPONENT_TRANSITION_OPACITY })
- 在ComponentTransition代碼中,定義一個isShow變量,用于控制Image子組件的添加和移除,在Button組件的onClick事件中添加animateTo方法,來使Image子組件子組件動效生效。
// ComponentTransition.ets @State isShow: boolean = false; Button($r('app.string.Component_transition_toggle')) .height(DimensionUtil.getVp($r('app.float.element_trans_btn_height'))) .width(DimensionUtil.getVp($r('app.float.element_trans_btn_width'))) .fontColor(Color.White) .backgroundColor($r('app.color.light_blue')) .onClick(() = > { animateTo({ duration: TRANSITION_ANIMATION_DURATION }, () = > { this.isShow = !this.isShow; }) })
共享元素轉場
效果如圖所示:
共享元素轉場通過給組件設置sharedTransition屬性來實現,兩個頁面的組件配置為同一個id,則轉場過程中會執行共享元素轉場。sharedTransition可以設置動效的時長、動畫曲線和延時,實現步驟如下:
- 在ShareItem.ets中給Image組件設置sharedTransition屬性,組件轉場id設置為“SHARE_TRANSITION_ID”。
// ShareItem.ets Image($r('app.media.bg_transition')) .width(FULL_LENGTH) .height(DimensionUtil.getVp($r('app.float.share_item_element_height'))) .borderRadius(DimensionUtil.getVp($r('app.float.share_item_radius'))) .margin({ bottom: DimensionUtil.getVp($r('app.float.share_item_element_margin_bottom')) }) .sharedTransition(SHARE_TRANSITION_ID, { duration: TRANSITION_ANIMATION_DURATION, curve: Curve.Smooth, delay: SHARE_ITEM_ANIMATION_DELAY }) .onClick(() = > { router.pushUrl({ url: SHARE_PAGE_URL }) .catch((err: Error) = > { hilog.error(DOMAIN, PREFIX, FORMAT, err); }); })
- 在SharePage.ets中給Image組件設置sharedTransition屬性,組件轉場id設置為“SHARE_TRANSITION_ID”。
// SharePage.ets @Entry @Component struct SharePage { build() { Column() { TransitionElement({ imgFit: ImageFit.Cover }) .sharedTransition(SHARE_TRANSITION_ID, { duration: SHARE_ITEM_DURATION, curve: Curve.Smooth, delay: SHARE_ITEM_ANIMATION_DELAY }) } } }
審核編輯 黃宇
-
開發板
+關注
關注
25文章
5129瀏覽量
98326 -
HarmonyOS
+關注
關注
79文章
1983瀏覽量
30630 -
OpenHarmony
+關注
關注
25文章
3753瀏覽量
16663 -
RK3568
+關注
關注
4文章
526瀏覽量
5261
發布評論請先 登錄
相關推薦
OpenHarmony實戰開發-如何實現模態轉場
【木棉花】ArkUI轉場動畫的使用——學習筆記
直播預告丨Hello HarmonyOS進階課程第四課——ArkUI動畫開發
【直播回顧】Hello HarmonyOS進階課程第四課——ArkUI動畫開發
HarmonyOS應用開發-ACE 2.0轉場動畫體驗
Harmony/OpenHarmony應用開發-轉場動畫頁面間轉場
Harmony/OpenHarmony應用開發-轉場動畫組件內轉場
HarmonyOS/OpenHarmony應用開發-轉場動畫共享元素轉場
HarmonyOS屬性動畫開發示例(ArkTS)
OpenHarmony實戰開發-如何實現組件動畫。
![OpenHarmony實戰<b class='flag-5'>開發</b>-如何實現組件<b class='flag-5'>動畫</b>。](https://file1.elecfans.com/web2/M00/DF/14/wKgaomYt_x2Ab_qaAAEJlEQIlYw492.jpg)
評論