1# 旋转屏动画 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @CCFFWW--> 5<!--Designer: @yangfan229--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9旋转屏动画主要分为两类:[布局切换的旋转屏动画](#布局切换的旋转屏动画)和[透明度变化的旋转屏动画](#透明度变化的旋转屏动画),旨在实现屏幕显示方向变化时的自然过渡。布局切换的旋转屏动画实现较为简便,例如在module.json5中配置自动旋转(或设置窗口显示方向)即可实现。而透明度变化的旋转屏动画则需在module.json5配置的基础上,预备两套视图,在屏幕旋转时,通过视图切换,使消失的视图呈现渐隐效果,新出现的视图则渐显,从而营造流畅的视觉体验。 10 11## 布局切换的旋转屏动画 12 13布局切换时的旋转屏动画,是在屏幕显示方向改变时,为窗口与应用视图同步旋转而设计的大小和位置过渡动画。这种布局切换的旋转屏动画是系统默认的,便于开发者实现。当屏幕显示方向变化时,系统会生成窗口旋转动画,并自动调整窗口大小以匹配旋转后的尺寸。在此过程中,窗口会通知对应的应用,要求其根据新的窗口大小重新布局,产生与窗口旋转动画参数相同的布局动画。 14 15切换屏幕方向即可实现布局切换的旋转屏动画效果。 16 17```ts 18// xx.ets 19@Entry 20@Component 21struct rotation { 22 23 build() { 24 Stack() { 25 Image($r('app.media.tree')) 26 .position({ x: 0, y: 0 }) 27 .size({ width: 100, height: 100 }) 28 .id('image1') 29 } 30 .backgroundColor(Color.White) 31 .size({ width: '100%', height: '100%' }) 32 } 33} 34``` 35 36需要在项目的module.json5文件中的abilities列表里添加"orientation",指定为"auto_rotation"。 37```json 38"orientation": "auto_rotation", 39``` 40 41布局切换的旋转屏动画,会对同步旋转的窗口与应用视图做大小和位置的过渡。 42 43 44 45## 透明度变化的旋转屏动画 46 47透明度变化的旋转屏动画在屏幕显示方向变化时启用,当窗口进行旋转动画时,为旋转过程中新增或删除的组件添加默认透明度转场,以实现组件的优雅出现和消失。此功能通过监听窗口旋转事件,在事件中切换组件的视图效果,如果消失视图的根节点和新出现视图的根节点未设置转场效果,会为其自动添加默认透明度转场(即[TransitionEffect](../reference/apis-arkui/arkui-ts/ts-transition-animation-component.md#transitioneffect10对象说明).OPACITY),展现出透明度的渐隐和渐显效果。 48 49```ts 50// xx.ets 51import { display } from '@kit.ArkUI'; 52 53@Entry 54@Component 55struct rotation { 56 57 // 获取通过监听窗口的windowsSizeChange事件得到的屏幕显示方向 58 @StorageLink('orientation') myOrientation: display.Orientation = display.Orientation.PORTRAIT; 59 60 build() { 61 Stack() { 62 63 // 当屏幕显示方向变化时,切换组件的视图效果 64 if (this.myOrientation == display.Orientation.PORTRAIT || this.myOrientation == display.Orientation.PORTRAIT_INVERTED) { 65 Image($r('app.media.sky')) 66 .size({ width: 100, height: 100 }) 67 .id('image1') 68 69 // 开发者也可以通过自行设置transition的TransitionEffect.OPACITY转场效果来实现旋转屏动画的透明度变化 70 // .transition(TransitionEffect.OPACITY) 71 } else { 72 Image($r('app.media.tree')) 73 .position({ x: 0, y: 0 }) 74 .size({ width: 200, height: 200 }) 75 .id('image2') 76 77 // 开发者也可以通过自行设置transition的TransitionEffect.OPACITY来实现旋转屏动画的透明度变化 78 // .transition(TransitionEffect.OPACITY) 79 } 80 } 81 .backgroundColor(Color.White) 82 .size({ width: '100%', height: '100%' }) 83 } 84} 85``` 86 87监听窗口旋转的同步事件windowsSizeChange来实现视图的切换。例如可在EntryAbility.ets文件的onWindowStageCreate方法中添加处理逻辑以获取屏幕的显示方向。 88```ts 89onWindowStageCreate(windowStage: window.WindowStage): void { 90 91 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 92 93 let mainWindow: window.Window; 94 try { 95 mainWindow = windowStage.getMainWindowSync(); 96 let displayClass: display.Display = display.getDefaultDisplaySync(); 97 AppStorage.setOrCreate('orientation', displayClass.orientation); 98 // 监听窗口的windowsSizeChange事件,旋转屏时会触发该事件 99 mainWindow.on('windowSizeChange', (data) => { 100 console.info('Succeeded in enabling the listener for window size changes. Data: ' + JSON.stringify(data)); 101 let displayClass: display.Display | null = null; 102 try { 103 displayClass = display.getDefaultDisplaySync(); 104 console.info('display orientation is ' + JSON.stringify(displayClass.orientation)); 105 // 获取屏幕的显示方向 106 AppStorage.set('orientation', displayClass.orientation); 107 } catch { 108 return; 109 } 110 }) 111 } catch { 112 hilog.error(0x0000, 'testTag', '%{public}s', 'error'); 113 return; 114 } 115 116 windowStage.loadContent('pages/Index', (err) => { 117 if (err.code) { 118 hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 119 return; 120 } 121 hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); 122 }); 123} 124``` 125 126需要在项目的 module.json5 文件中的 abilities 列表里添加 "orientation",指定为 "auto_rotation"。 127```json 128"orientation": "auto_rotation", 129``` 130 131透明度变化的旋转屏动画,会对窗口做大小和位置的过渡,并同时对应用视图做切换过渡,且为消失隐藏的应用视图做渐隐效果,对新出现的视图做渐显的效果。 132 133