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