• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.None36
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.PushRouteType.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![pageTransition_PushPop](figures/pageTransition_PushPop.gif)
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![pageTransition_None](figures/pageTransition_None.gif)
364