1# 页面转场动画(不推荐) 2 3为了实现更好的转场效果,推荐使用[导航转场](arkts-navigation-transition.md)和[模态转场](arkts-modal-transition.md)。 4 5 6两个页面间发生跳转,一个页面消失,另一个页面出现,这时可以配置各自页面的页面转场参数实现自定义的页面转场效果。[页面转场](../reference/arkui-ts/ts-page-transition-animation.md)效果写在pageTransition函数中,通过PageTransitionEnter和PageTransitionExit指定页面进入和退出的动画效果。 7 8 9PageTransitionEnter的接口为: 10 11 12 13```ts 14PageTransitionEnter({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number}) 15``` 16 17 18PageTransitionExit的接口为: 19 20 21 22```ts 23PageTransitionExit({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number}) 24``` 25 26 27上述接口定义了PageTransitionEnter和PageTransitionExit组件,可通过slide、translate、scale、opacity属性定义不同的页面转场效果。对于PageTransitionEnter而言,这些效果表示入场时起点值,对于PageTransitionExit而言,这些效果表示退场的终点值,这一点与组件转场transition配置方法类似。此外,PageTransitionEnter提供了onEnter接口进行自定义页面入场动画的回调,PageTransitionExit提供了onExit接口进行自定义页面退场动画的回调。 28 29 30上述接口中的参数type,表示路由生效的类型,这一点开发者容易混淆其含义。页面转场的两个页面,必定有一个页面退出,一个页面进入。如果通过router.pushUrl操作从页面A跳转到页面B,则页面A退出,做页面退场动画,页面B进入,做页面入场动画。如果通过router.back操作从页面B返回到页面A,则页面B退出,做页面退场动画,页面A进入,做页面入场动画。即页面的PageTransitionEnter既可能是由于新增页面(push,入栈)引起的新页面的入场动画,也可能是由于页面返回(back,或pop,出栈)引起的页面栈中老页面的入场动画,为了能区分这两种形式的入场动画,提供了type参数,这样开发者能完全定义所有类型的页面转场效果。 31 32 33## type配置为RouteType.None 34 35type为RouteType.None表示对页面栈的push、pop操作均生效,type的默认值为RouteType.None。 36 37 38```ts 39// page A 40pageTransition() { 41 // 定义页面进入时的效果,从左侧滑入,时长为1200ms,无论页面栈发生push还是pop操作均可生效 42 PageTransitionEnter({ type: RouteType.None, duration: 1200 }) 43 .slide(SlideEffect.Left) 44 // 定义页面退出时的效果,向左侧滑出,时长为1000ms,无论页面栈发生push还是pop操作均可生效 45 PageTransitionExit({ type: RouteType.None, duration: 1000 }) 46 .slide(SlideEffect.Left) 47} 48``` 49 50 51 52```ts 53// page B 54pageTransition() { 55 // 定义页面进入时的效果,从右侧滑入,时长为1000ms,无论页面栈发生push还是pop操作均可生效 56 PageTransitionEnter({ type: RouteType.None, duration: 1000 }) 57 .slide(SlideEffect.Right) 58 // 定义页面退出时的效果,向右侧滑出,时长为1200ms,无论页面栈发生push还是pop操作均可生效 59 PageTransitionExit({ type: RouteType.None, duration: 1200 }) 60 .slide(SlideEffect.Right) 61} 62``` 63 64 65假设页面跳转配置为多实例模式,即页面栈中允许存在重复的页面。可能会有4种场景,对应的页面转场效果如下表。 66 67 68| 路由操作 | 页面A转场效果 | 页面B转场效果 | 69| ---------------------------- | ---------------------------------- | ---------------------------------- | 70| router.pushUrl,从页面A跳转到新增的页面B | 页面退出,PageTransitionExit生效,向左侧滑出屏幕 | 页面进入,PageTransitionEnter生效,从右侧滑入屏幕 | 71| router.back,从页面B返回到页面A | 页面进入,PageTransitionEnter生效,从左侧滑入屏幕 | 页面退出,PageTransitionExit生效,向右侧滑出屏幕 | 72| router.pushUrl,从页面B跳转到新增的页面A | 页面进入,PageTransitionEnter生效,从左侧滑入屏幕 | 页面退出,PageTransitionExit生效,向右侧滑出屏幕 | 73| router.back,从页面A返回到页面B | 页面退出,PageTransitionExit生效,向左侧滑出屏幕 | 页面进入,PageTransitionEnter生效,从右侧滑入屏幕 | 74 75 76如果希望pushUrl进入的页面总是从右侧滑入,back时退出的页面总是从右侧滑出,则上表中的第3、4种情况不满足要求,那么需要完整的定义4个页面转场效果。 77 78 79## type配置为RouteType.Push或RouteType.Pop 80 81type为RouteType.Push表示仅对页面栈的push操作生效,type为RouteType.Pop表示仅对页面栈的pop操作生效。 82 83 84```ts 85// page A 86pageTransition() { 87 // 定义页面进入时的效果,从右侧滑入,时长为1200ms,页面栈发生push操作时该效果才生效 88 PageTransitionEnter({ type: RouteType.Push, duration: 1200 }) 89 .slide(SlideEffect.Right) 90 // 定义页面进入时的效果,从左侧滑入,时长为1200ms,页面栈发生pop操作时该效果才生效 91 PageTransitionEnter({ type: RouteType.Pop, duration: 1200 }) 92 .slide(SlideEffect.Left) 93 // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效 94 PageTransitionExit({ type: RouteType.Push, duration: 1000 }) 95 .slide(SlideEffect.Left) 96 // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效 97 PageTransitionExit({ type: RouteType.Pop, duration: 1000 }) 98 .slide(SlideEffect.Right) 99} 100``` 101 102 103 104```ts 105// page B 106pageTransition() { 107 // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效 108 PageTransitionEnter({ type: RouteType.Push, duration: 1000 }) 109 .slide(SlideEffect.Right) 110 // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效 111 PageTransitionEnter({ type: RouteType.Pop, duration: 1000 }) 112 .slide(SlideEffect.Left) 113 // 定义页面退出时的效果,向左侧滑出,时长为1200ms,页面栈发生push操作时该效果才生效 114 PageTransitionExit({ type: RouteType.Push, duration: 1200 }) 115 .slide(SlideEffect.Left) 116 // 定义页面退出时的效果,向右侧滑出,时长为1200ms,页面栈发生pop操作时该效果才生效 117 PageTransitionExit({ type: RouteType.Pop, duration: 1200 }) 118 .slide(SlideEffect.Right) 119} 120``` 121 122 123以上代码则完整的定义了所有可能的页面转场样式。假设页面跳转配置为多实例模式,即页面栈中允许存在重复的页面。可能会有4种场景,对应的页面转场效果如下表。 124 125 126| 路由操作 | 页面A转场效果 | 页面B转场效果 | 127| ---------------------------- | ---------------------------------------- | ---------------------------------------- | 128| router.pushUrl,从页面A跳转到新增的页面B | 页面退出,PageTransitionExit且type为RouteType.Push的转场样式生效,向左侧滑出屏幕 | 页面进入,PageTransitionEnter且type为RouteType.Push的转场样式生效,从右侧滑入屏幕 | 129| router.back,从页面B返回到页面A | 页面进入,PageTransitionEnter且type为RouteType.Pop的转场样式生效,从左侧滑入屏幕 | 页面退出,PageTransitionExit且type为RouteType.Pop的转场样式生效,向右侧滑出屏幕 | 130| router.pushUrl,从页面B跳转到新增的页面A | 页面进入,PageTransitionEnter且type为RouteType.Push的转场样式生效,从右侧滑入屏幕 | 页面退出,PageTransitionExit且type为RouteType.Push的转场样式生效,向左侧滑出屏幕 | 131| router.back,从页面A返回到页面B | 页面退出,PageTransitionExit且type为RouteType.Pop的转场样式生效,向右侧滑出屏幕 | 页面进入,PageTransitionEnter且type为RouteType.Pop的转场样式生效,从左侧滑入屏幕 | 132 133 134>**说明:** 135> 136> 1. 由于每个页面的页面转场样式都可由开发者独立配置,而页面转场涉及到两个页面,开发者应考虑两个页面的页面转场效果的衔接,如时长尽量保持一致。 137> 138> 2. 如果没有定义匹配的页面转场样式,则该页面使用系统默认的页面转场样式。 139 140 141## 禁用某页面的页面转场 142 143 144```ts 145pageTransition() { 146 PageTransitionEnter({ type: RouteType.None, duration: 0 }) 147 PageTransitionExit({ type: RouteType.None, duration: 0 }) 148} 149``` 150 151 152通过设置页面转场的时长为0,可使该页面无页面转场动画。 153 154 155## 场景示例 156 157下面介绍定义了所有的四种页面转场样式的页面转场动画示例。 158 159 160 161```ts 162// PageTransitionSrc1 163import router from '@ohos.router'; 164@Entry 165@Component 166struct PageTransitionSrc1 { 167 build() { 168 Column() { 169 Image($r('app.media.mountain')) 170 .width('90%') 171 .height('80%') 172 .objectFit(ImageFit.Fill) 173 .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成 174 .margin(30) 175 176 Row({ space: 10 }) { 177 Button("pushUrl") 178 .onClick(() => { 179 // 路由到下一个页面,push操作 180 router.pushUrl({ url: 'pages/myTest/pageTransitionDst1' }); 181 }) 182 Button("back") 183 .onClick(() => { 184 // 返回到上一页面,相当于pop操作 185 router.back(); 186 }) 187 }.justifyContent(FlexAlign.Center) 188 } 189 .width("100%").height("100%") 190 .alignItems(HorizontalAlign.Center) 191 } 192 193 pageTransition() { 194 // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效 195 PageTransitionEnter({ type: RouteType.Push, duration: 1000 }) 196 .slide(SlideEffect.Right) 197 // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效 198 PageTransitionEnter({ type: RouteType.Pop, duration: 1000 }) 199 .slide(SlideEffect.Left) 200 // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效 201 PageTransitionExit({ type: RouteType.Push, duration: 1000 }) 202 .slide(SlideEffect.Left) 203 // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效 204 PageTransitionExit({ type: RouteType.Pop, duration: 1000 }) 205 .slide(SlideEffect.Right) 206 } 207} 208``` 209 210 211 212 213```ts 214// PageTransitionDst1 215import router from '@ohos.router'; 216@Entry 217@Component 218struct PageTransitionDst1 { 219 build() { 220 Column() { 221 Image($r('app.media.forest')) 222 .width('90%') 223 .height('80%') 224 .objectFit(ImageFit.Fill) 225 .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成 226 .margin(30) 227 228 Row({ space: 10 }) { 229 Button("pushUrl") 230 .onClick(() => { 231 // 路由到下一页面,push操作 232 router.pushUrl({ url: 'pages/myTest/pageTransitionSrc1' }); 233 }) 234 Button("back") 235 .onClick(() => { 236 // 返回到上一页面,相当于pop操作 237 router.back(); 238 }) 239 }.justifyContent(FlexAlign.Center) 240 } 241 .width("100%").height("100%") 242 .alignItems(HorizontalAlign.Center) 243 } 244 245 pageTransition() { 246 // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效 247 PageTransitionEnter({ type: RouteType.Push, duration: 1000 }) 248 .slide(SlideEffect.Right) 249 // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效 250 PageTransitionEnter({ type: RouteType.Pop, duration: 1000 }) 251 .slide(SlideEffect.Left) 252 // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效 253 PageTransitionExit({ type: RouteType.Push, duration: 1000 }) 254 .slide(SlideEffect.Left) 255 // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效 256 PageTransitionExit({ type: RouteType.Pop, duration: 1000 }) 257 .slide(SlideEffect.Right) 258 } 259} 260``` 261 262 263 264 265 266 267下面介绍使用了type为None的页面转场动画示例。 268 269 270 271```ts 272// PageTransitionSrc2 273import router from '@ohos.router'; 274@Entry 275@Component 276struct PageTransitionSrc2 { 277 build() { 278 Column() { 279 Image($r('app.media.mountain')) 280 .width('90%') 281 .height('80%') 282 .objectFit(ImageFit.Fill) 283 .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成 284 .margin(30) 285 286 Row({ space: 10 }) { 287 Button("pushUrl") 288 .onClick(() => { 289 // 路由到下一页面,push操作 290 router.pushUrl({ url: 'pages/myTest/pageTransitionDst2' }); 291 }) 292 Button("back") 293 .onClick(() => { 294 // 返回到上一页面,相当于pop操作 295 router.back(); 296 }) 297 }.justifyContent(FlexAlign.Center) 298 } 299 .width("100%").height("100%") 300 .alignItems(HorizontalAlign.Center) 301 } 302 303 pageTransition() { 304 // 定义页面进入时的效果,从左侧滑入,时长为1000ms,无论页面栈发生push还是pop操作均可生效 305 PageTransitionEnter({ duration: 1000 }) 306 .slide(SlideEffect.Left) 307 // 定义页面退出时的效果,相对于正常页面位置x方向平移100vp,y方向平移100vp,透明度变为0,时长为1200ms,无论页面栈发生push还是pop操作均可生效 308 PageTransitionExit({ duration: 1200 }) 309 .translate({ x: 100.0, y: 100.0 }) 310 .opacity(0) 311 } 312} 313``` 314 315 316 317```ts 318// PageTransitionDst2 319import router from '@ohos.router'; 320@Entry 321@Component 322struct PageTransitionDst2 { 323 build() { 324 Column() { 325 Image($r('app.media.forest')) 326 .width('90%') 327 .height('80%') 328 .objectFit(ImageFit.Fill) 329 .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成 330 .margin(30) 331 332 Row({ space: 10 }) { 333 Button("pushUrl") 334 .onClick(() => { 335 // 路由到下一页面,push操作 336 router.pushUrl({ url: 'pages/myTest/pageTransitionSrc2' }); 337 }) 338 Button("back") 339 .onClick(() => { 340 // 返回到上一页面,相当于pop操作 341 router.back(); 342 }) 343 }.justifyContent(FlexAlign.Center) 344 } 345 .width("100%").height("100%") 346 .alignItems(HorizontalAlign.Center) 347 } 348 349 pageTransition() { 350 // 定义页面进入时的效果,从左侧滑入,时长为1200ms,无论页面栈发生push还是pop操作均可生效 351 PageTransitionEnter({ duration: 1200 }) 352 .slide(SlideEffect.Left) 353 // 定义页面退出时的效果,相对于正常页面位置x方向平移100vp,y方向平移100vp,透明度变为0,时长为1000ms,无论页面栈发生push还是pop操作均可生效 354 PageTransitionExit({ duration: 1000 }) 355 .translate({ x: 100.0, y: 100.0 }) 356 .opacity(0) 357 } 358} 359``` 360 361 362 363 364