1# 安全区域 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @WendongPang--> 5<!--Designer: @lanshouren--> 6<!--Tester: @liuli0427--> 7<!--Adviser: @HelloCrease--> 8 9安全区域是指页面的显示区域,默认情况下开发者开发的界面都布局在安全区域内,不与系统设置的避让区比如状态栏、导航栏区域重叠。提供属性方法允许开发者设置组件绘制内容突破安全区域的限制,通过[expandSafeArea](#expandsafearea)属性支持组件不改变布局情况下扩展其绘制区域至安全区外,通过设置[setKeyboardAvoidMode](#setkeyboardavoidmode11)来配置虚拟键盘弹出时页面的避让模式。页面中有标题栏等文字不希望和避让区重叠时,建议对组件设置expandSafeArea属性实现沉浸式效果,也可以直接通过窗口接口[setWindowLayoutFullScreen](../arkts-apis-window-Window.md#setwindowlayoutfullscreen9)设置全屏沉浸式。 10 11> **说明:** 12> 13> 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。<br /> 14> 摄像头挖孔区域不属于避让区,页面默认不避让挖孔。<br /> 15> 从API Version 12开始,可在module.json5中添加以下配置项,摄像头挖孔区域会视为避让区,实现页面默认避让挖孔:<br /> 16 "metadata": [<br /> 17 {<br /> 18 "name": "avoid_cutout",<br /> 19 "value": "true",<br /> 20 }<br /> 21 ],<br /> 22 23 24## expandSafeArea 25 26expandSafeArea(types?: Array<SafeAreaType>, edges?: Array<SafeAreaEdge>): T 27 28控制组件扩展其安全区域。 29 30**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 31 32**系统能力:** SystemCapability.ArkUI.ArkUI.Full 33 34**参数:** 35 36| 参数名 | 类型 | 必填 | 说明 | 37| ------ | -------------------------------------------------- | ---- | ------------------------------------------------------------ | 38| types | Array <[SafeAreaType](#safeareatype)> | 否 | 配置扩展安全区域的类型。未添加[Metadata](../../apis-ability-kit/js-apis-bundleManager-metadata.md)配置项时,页面不避让挖孔,CUTOUT类型不生效。<br />默认值:[SafeAreaType.SYSTEM, SafeAreaType.CUTOUT, SafeAreaType.KEYBOARD] <br />非法值:按默认值处理。| 39| edges | Array <[SafeAreaEdge](#safeareaedge)> | 否 | 配置扩展安全区域的方向。<br />默认值:[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM, SafeAreaEdge.START, SafeAreaEdge.END] <br />非法值:按默认值处理。<br />扩展至所有避让区域。 | 40 41**返回值:** 42 43| 类型 | 说明 | 44| --- | --- | 45| T | 返回当前组件。 | 46 47> **说明:** 48> 49> 设置expandSafeArea属性进行组件绘制扩展时,建议组件尺寸不要设置固定宽高(百分比除外),当设置固定宽高(包括设置"auto")时,扩展安全区域的方向只支持[SafeAreaEdge.TOP, SafeAreaEdge.START],扩展后的组件尺寸保持不变。 50> 51> 安全区域不会限制内部组件的布局和大小,不会裁剪内部组件。 52> 53> 当父容器是滚动容器时,设置expandSafeArea属性不生效。 54> 55> 设置expandSafeArea()时,不传参,走默认值处理;设置expandSafeArea([],[])时,相当于入参是空数组,此时设置expandSafeArea属性不生效。 56> 57> 组件设置expandSafeArea生效的条件为: 58> 1.type为SafeAreaType.KEYBOARD时默认生效,表现为组件不避让键盘。<br/> 59> 2.设置其他type,组件的边界与安全区域重合时组件能够延伸到安全区域下。例如:设备顶部状态栏高度100,那么组件在屏幕中的绝对位置需要为0 <= y <= 100。 60> 61> 组件延伸到避让区时,在避让区的事件如点击事件等可能会被系统拦截,优先给状态栏等系统组件响应。 62> 63> 滚动类容器内的组件不建议设置expandSafeArea属性,如果设置,需要按照组件嵌套关系,将当前节点到滚动类祖先容器间所有直接节点设置expandSafeArea属性,否则expandSafeArea属性在滚动后可能会失效,写法参考[示例7](#示例7滚动类容器扩展安全区)。 64> 65> expandSafeArea属性仅作用于当前组件,不会向父组件或子组件传递,因此使用过程中,所有相关组件均需配置。 66> 67> 同时设置expandSafeArea和position属性时,position属性会优先生效,expandSafeArea属性会后生效。对于未设置position、offset等绘制属性的组件,如果其边界未与避让区重叠,设置expandSafeArea属性将不生效,如弹窗和半模态组件。 68> 69> 对于expandSafeArea属性无法生效的场景,若要将组件部署在避让区,需要手动调整组件的坐标。 70 71## SafeAreaType 72 73扩展安全区域的枚举类型。 74 75**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 76 77**系统能力:** SystemCapability.ArkUI.ArkUI.Full 78 79| 名称 | 值 | 说明 | 80| ------- | ---- | ---------------------------------- | 81| SYSTEM |-| 系统默认非安全区域,包括状态栏、导航栏。 | 82| CUTOUT |- | 设备的非安全区域,例如刘海屏或挖孔屏区域。 | 83| KEYBOARD |- |软键盘区域。 | 84 85## SafeAreaEdge 86 87扩展安全区域的方向。 88 89**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 90 91**系统能力:** SystemCapability.ArkUI.ArkUI.Full 92 93| 名称 | 值 | 说明 | 94| ------- | ---- | ---------------------------------- | 95| TOP |-| 上方区域。 | 96| BOTTOM |-| 下方区域。 | 97| START |-| 前部区域。 | 98| END |-| 尾部区域。 | 99 100## setKeyboardAvoidMode<sup>11+</sup> 101 102setKeyboardAvoidMode(value: KeyboardAvoidMode): void 103 104控制虚拟键盘抬起时页面的避让模式。 105 106**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 107 108**系统能力:** SystemCapability.ArkUI.ArkUI.Full 109 110**参数:** 111 112| 参数名 | 类型 | 必填 | 说明 | 113| ------ | ---------------------------------------------------- | ---- | ------------------------------------------------------------ | 114| value | [KeyboardAvoidMode](../arkts-apis-uicontext-e.md#keyboardavoidmode11) | 是 | 配置虚拟键盘抬起时页面的避让模式。<br />默认值:KeyboardAvoidMode.OFFSET,键盘抬起时默认避让模式为上抬。 | 115 116> **说明:** 117> 118> KeyboardAvoidMode.RESIZE模式会压缩页面大小,页面中设置百分比宽高的组件会跟随页面压缩,而直接设置宽高的组件会按设置的固定大小布局。设置KeyboardAvoidMode的RESIZE模式时,expandSafeArea([SafeAreaType.KEYBOARD],[SafeAreaEdge.BOTTOM])不生效。 119> 120> KeyboardAvoidMode.NONE模式配置页面不避让键盘,页面会被抬起的键盘遮盖。 121> 122> setKeyboardAvoidMode针对页面生效,对于弹窗类组件不生效,比如Dialog、Popup、Menu、BindSheet、BindContentCover、Toast、OverlayManager。弹窗类组件的避让模式可以参考[CustomDialogControllerOptions对象说明](./ts-methods-custom-dialog-box.md#customdialogcontrolleroptions对象说明)。 123 124## getKeyboardAvoidMode<sup>11+</sup> 125 126getKeyboardAvoidMode(): KeyboardAvoidMode 127 128返回虚拟键盘抬起时页面的避让模式。 129 130**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 131 132**系统能力:** SystemCapability.ArkUI.ArkUI.Full 133 134**返回值:** 135 136| 名称 | 说明 | 137| ---------------------------------------------------- | ---------------------------------- | 138| [KeyboardAvoidMode](../arkts-apis-uicontext-e.md#keyboardavoidmode11) | 返回虚拟键盘抬起时的页面避让模式。 | 139 140## ignoreLayoutSafeArea<sup>20+</sup> 141 142ignoreLayoutSafeArea(types?: Array<LayoutSafeAreaType>, edges?: Array<LayoutSafeAreaEdge>): T 143 144扩展组件布局时的安全区。 145 146**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。 147 148**系统能力:** SystemCapability.ArkUI.ArkUI.Full 149 150**参数:** 151 152| 参数名 | 类型 | 必填 | 说明 | 153| ------ | -------------------------------------------------- | ---- | ------------------------------------------------------------ | 154| types | Array <[LayoutSafeAreaType](#layoutsafeareatype12)> | 否 | 扩展布局安全区域的类型。<br />默认值:[LayoutSafeAreaType.SYSTEM],扩展至所有安全区域,比如:状态栏,导航栏和[组件级安全区(safeAreaPadding)](./ts-universal-attributes-size.md#safeareapadding14)。<br />非法值:按默认值处理。 | 155| edges | Array <[LayoutSafeAreaEdge](#layoutsafeareaedge12)> | 否 | 扩展布局安全区的边缘,并且支持镜像能力。<br />默认值:[LayoutSafeAreaEdge.ALL],扩展组件所有边缘。<br />非法值:按默认值处理。| 156 157**返回值:** 158 159| 类型 | 说明 | 160| --- | --- | 161| T | 返回当前组件。 | 162 163> **说明:** 164> 165> 忽略布局安全区边缘的组件,如果其宽度或高度设置了[LayoutPolicy.matchParent](ts-universal-attributes-size.md#layoutpolicy15),其大小和位置都会改变,否则仅改变其位置。 166> 167> 依据safeAreaPadding累积功能,组件可扩展其安全区边缘到所有能感知的连续安全区域。 168> 169> 滚动类组件的子元素忽略布局安全区边缘时在滚动方向不考虑滚动组件自身及其父组件的安全区域,包括:List、ArcListItem、Grid、WaterFlow、Swiper和Tabs。 170> 171> 忽略布局安全区属性.ignoreLayoutSafeArea和忽略渲染安全区属性.expandSafeArea都设置时,.ignoreLayoutSafeArea先生效,.expandSafeArea在前者基础上再生效。 172 173## LayoutSafeAreaType<sup>12+</sup> 174 175扩展布局安全区域的枚举类型。 176 177**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 178 179**系统能力:** SystemCapability.ArkUI.ArkUI.Full 180 181| 名称 | 值 | 说明 | 182| ------- | ---- | ---------------------------------- | 183| SYSTEM | 0 |设置后,组件的布局范围可扩展至[组件级安全区(safeAreaPadding)](./ts-universal-attributes-size.md#safeareapadding14)和页面级安全区(状态栏、导航栏、挖孔区)。 | 184 185## LayoutSafeAreaEdge<sup>12+</sup> 186 187扩展安全区域的方向。 188 189**系统能力:** SystemCapability.ArkUI.ArkUI.Full 190 191| 名称 | 值 | 说明 | 192| ------- | ---- | ---------------------------------- | 193| TOP | 0 | 上方区域。<br>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 194| BOTTOM | 1 | 下方区域。<br>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 195| START<sup>20+</sup> | 2 | 前部区域。LTR模式时表示左侧区域,RTL模式表示右侧区域。<br>**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。 | 196| END<sup>20+</sup> | 3 |尾部区域。LTR模式时表示右侧区域,RTL模式表示左侧区域。<br>**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。 | 197| VERTICAL<sup>20+</sup> | 4 |垂直区域。<br>**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。 | 198| HORIZONTAL<sup>20+</sup> | 5 |水平区域。<br>**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。 | 199| ALL<sup>20+</sup> | 6 |全部区域。<br>**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。 | 200 201## 示例 202 203### 示例1(实现沉浸式效果) 204 205该示例通过设置expandSafeArea属性向顶部和底部扩展安全区实现沉浸式效果。 206 207```ts 208// xxx.ets 209@Entry 210@Component 211struct SafeAreaExample1 { 212 @State text: string = '' 213 controller: TextInputController = new TextInputController() 214 215 build() { 216 Row() { 217 Column() 218 .height('100%').width('100%') 219 .backgroundImage($r('app.media.bg')).backgroundImageSize(ImageSize.Cover) 220 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) 221 }.height('100%') 222 } 223} 224``` 225 226 227 228### 示例2(同时设置固定宽高和expandSafeArea属性) 229 230该示例展示了同时设置固定宽高和expandSafeArea属性的效果。 231 232```ts 233// xxx.ets 234@Entry 235@Component 236struct SafeAreaExample2 { 237 @State text: string = '' 238 controller: TextInputController = new TextInputController() 239 240 build() { 241 Column() { 242 TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller }) 243 .placeholderFont({ size: 14, weight: 400 }) 244 .width(320).height(40).offset({y: 120}) 245 .fontSize(14).fontColor(Color.Black) 246 .backgroundColor(Color.White) 247 } 248 .height('780') 249 .width('100%') 250 .backgroundColor('rgb(179,217,235)') 251 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) 252 } 253} 254``` 255 256如下图:Column组件扩展至了顶部状态栏[SafeAreaEdge.TOP],未扩展至底部导航条[SafeAreaEdge.BOTTOM],扩展后的组件高度与设置的高度一致。 257 258 259 260 261### 示例3(键盘避让时固定背景图位置) 262 263该示例通过为背景图组件设置expandSafeArea属性,来实现拉起键盘进行避让时,背景图保持不动的效果。 264 265```ts 266// xxx.ets 267@Entry 268@Component 269struct SafeAreaExample3 { 270 @State text: string = '' 271 controller: TextInputController = new TextInputController() 272 273 build() { 274 Row() { 275 Stack() { 276 Column() 277 .height('100%').width('100%') 278 .backgroundImage($r('app.media.bg')).backgroundImageSize(ImageSize.Cover) 279 .expandSafeArea([SafeAreaType.KEYBOARD, SafeAreaType.SYSTEM]) 280 Column() { 281 Button('Set caretPosition 1') 282 .onClick(() => { 283 this.controller.caretPosition(1) 284 }) 285 TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller }) 286 .placeholderFont({ size: 14, weight: 400 }) 287 .width(320).height(40).offset({y: 120}) 288 .fontSize(14).fontColor(Color.Black) 289 .backgroundColor(Color.White) 290 }.width('100%').alignItems(HorizontalAlign.Center) 291 } 292 }.height('100%') 293 } 294} 295``` 296 297 298 299### 示例4(设置键盘避让模式为压缩) 300 301该示例通过调用setKeyboardAvoidMode设置键盘避让模式为RESIZE模式,实现键盘抬起时page的压缩效果。 302 303<!--code_no_check--> 304```ts 305// EntryAbility.ets 306import { KeyboardAvoidMode } from '@kit.ArkUI'; 307export default class EntryAbility extends UIAbility{ 308 onWindowStageCreate(windowStage: window.WindowStage) { 309 // Main window is created, set main page for this ability 310 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 311 312 windowStage.loadContent('pages/Index', (err, data) => { 313 let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode(); 314 // 设置虚拟键盘抬起时压缩页面大小为减去键盘的高度 315 windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE); 316 if (err.code) { 317 hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 318 return; 319 } 320 hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 321 }); 322 } 323} 324``` 325 326```ts 327// xxx.ets 328@Entry 329@Component 330struct KeyboardAvoidExample1 { 331 build() { 332 Column() { 333 Row().height("30%").width("100%").backgroundColor(Color.Gray) 334 TextArea().width("100%").borderWidth(1) 335 Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor('rgb(179,217,235)').layoutWeight(1) 336 }.width('100%').height("100%") 337 } 338} 339``` 340 341 342 343### 示例5(设置键盘避让模式为上抬) 344 345该示例通过调用setKeyboardAvoidMode设置键盘避让模式为OFFSET模式,实现键盘抬起时page的上抬效果。但当输入光标距离屏幕底部的高度大于键盘高度时,page不会抬起,如本例中所示。 346 347<!--code_no_check--> 348```ts 349// EntryAbility.ets 350import { KeyboardAvoidMode } from '@kit.ArkUI'; 351export default class EntryAbility extends UIAbility{ 352 onWindowStageCreate(windowStage: window.WindowStage) { 353 // Main window is created, set main page for this ability 354 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 355 356 windowStage.loadContent('pages/Index', (err, data) => { 357 let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode(); 358 // 设置虚拟键盘抬起时把页面上抬直到露出光标 359 windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.OFFSET); 360 if (err.code) { 361 hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 362 return; 363 } 364 hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 365 }); 366 } 367} 368``` 369 370```ts 371// xxx.ets 372@Entry 373@Component 374struct KeyboardAvoidExample2 { 375 build() { 376 Column() { 377 Row().height("30%").width("100%").backgroundColor(Color.Gray) 378 TextArea().width("100%").borderWidth(1) 379 Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor('rgb(179,217,235)').layoutWeight(1) 380 }.width('100%').height("100%") 381 } 382} 383``` 384 385 386 387### 示例6(切换避让模式) 388 389该示例通过调用setKeyboardAvoidMode来实现OFFSET、RESIZE和NONE模式之间的切换,实现三种不同的键盘避让效果。 390 391```ts 392import { hilog } from '@kit.PerformanceAnalysisKit'; 393import { KeyboardAvoidMode } from '@kit.ArkUI'; 394@Entry 395@Component 396 397struct KeyboardAvoidExample3 { 398 build() { 399 Column() { 400 Row({space:15}) { 401 Button('OFFSET') 402 .onClick(() => { 403 this.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.OFFSET); 404 hilog.info(0x0000, 'keyboardAvoidMode: %{public}s', JSON.stringify(this.getUIContext().getKeyboardAvoidMode())); 405 }) 406 .layoutWeight(1) 407 Button('RESIZE') 408 .onClick(() => { 409 this.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE); 410 hilog.info(0x0000, 'keyboardAvoidMode: %{public}s', JSON.stringify(this.getUIContext().getKeyboardAvoidMode())); 411 }) 412 .layoutWeight(1) 413 Button('NONE') 414 .onClick(() => { 415 this.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.NONE); 416 hilog.info(0x0000, 'keyboardAvoidMode: %{public}s', JSON.stringify(this.getUIContext().getKeyboardAvoidMode())); 417 }) 418 .layoutWeight(1) 419 } 420 .height("30%") 421 .width("100%") 422 .backgroundColor(Color.Gray) 423 424 TextArea() 425 .width("100%") 426 .borderWidth(1) 427 428 Text("I can see the bottom of the page") 429 .width("100%") 430 .textAlign(TextAlign.Center) 431 .backgroundColor('rgb(179,217,235)') 432 .layoutWeight(1) 433 434 TextArea() 435 .width("100%") 436 .borderWidth(1) 437 } 438 .width('100%') 439 .height("100%") 440 } 441} 442``` 443OFFSET模式 444 445 446 447RESIZE模式 448 449 450 451NONE模式 452 453 454 455### 示例7(滚动类容器扩展安全区) 456 457该示例通过在滚动类容器内调用expandSafeArea属性实现沉浸式效果,Scroll内的Swiper可以延伸到状态栏上。 458 459```ts 460class SwiperDataSource implements IDataSource { 461 private list: Array<Color> = [] 462 constructor(list: Array<Color>) { 463 this.list = list 464 } 465 totalCount(): number { 466 return this.list.length 467 } 468 getData(index: number): Color { 469 return this.list[index] 470 } 471 registerDataChangeListener(listener: DataChangeListener): void { 472 } 473 unregisterDataChangeListener(listener: DataChangeListener): void { 474 } 475} 476@Entry 477@Component 478struct ExpandSafeAreaTest { 479 private swiperController: SwiperController = new SwiperController() 480 private swiperData: SwiperDataSource = new SwiperDataSource([]) 481 private list: Array<Color> = [ 482 Color.Pink, 483 Color.Blue, 484 Color.Green 485 ] 486 aboutToAppear(): void { 487 this.swiperData = new SwiperDataSource(this.list) 488 } 489 build() { 490 Scroll() { 491 Column() { 492 Swiper(this.swiperController) { 493 LazyForEach(this.swiperData, (item: Color, index: number) => { 494 Column() { 495 Text('banner' + index).fontSize(50).fontColor(Color.White) 496 } 497 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) 498 .width('100%') 499 .height(400) 500 .backgroundColor(item) 501 }) 502 } 503 .loop(true) 504 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) 505 .clip(false) 506 Column(){ 507 Text("Tab页Content").fontSize(50) 508 }.width("100%").height(1000) 509 .backgroundColor(Color.Grey) 510 }.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) 511 } 512 .clip(false) 513 .edgeEffect(EdgeEffect.None) 514 .width("100%").height("100%") 515 } 516} 517``` 518 519 520### 示例8(ignoreLayoutSafeArea延伸组件布局范围) 521 522该示例利用[ignoreLayoutSafeArea](#ignorelayoutsafearea20)改变组件位置。相比未使用该属性,配置ignoreLayoutSafeArea后,Row组件基于Stack内容区、Stack组件级安全区、系统状态栏共同组成的范围,取其左上部分,作左上对齐。 523 524```ts 525import { LengthMetrics } from '@kit.ArkUI' 526 527@Entry 528@Component 529struct IgnoreLayoutSafeAreaTest1 { 530 build() { 531 Column() { 532 Stack() { 533 Row() 534 .backgroundColor('rgb(39, 135, 217)') 535 .width(75) // 固定宽度 536 .height(75) // 固定高度 537 .ignoreLayoutSafeArea([LayoutSafeAreaType.SYSTEM], [LayoutSafeAreaEdge.START, LayoutSafeAreaEdge.TOP]) // 设置布局区域延伸取左和上方向,至系统避让区SYSTEM 538 539 Row() 540 .backgroundColor('rgb(0, 74, 175)') 541 .width(75) 542 .height(75) 543 544 } 545 .width(200) 546 .height(200) 547 .backgroundColor(Color.Gray) 548 .align(Alignment.TopStart) // 子组件相对于Stack容器左上对齐 549 .padding({ 550 left: 10 // 设置左侧10vp普通内边距 551 }) 552 .safeAreaPadding(LengthMetrics.vp(10)) // 设置10vp安全区内边距(即组件级安全区) 553 } 554 .width("100%") 555 } 556} 557``` 558 559 560### 示例9(ignoreLayoutSafeArea配合LayoutPolicy.matchParent延伸组件布局范围) 561 562该示例利用[ignoreLayoutSafeArea](#ignorelayoutsafearea20)和[LayoutPolicy.matchParent](ts-universal-attributes-size.md#layoutpolicy15)同时改变组件大小和位置。相比未使用该属性,配置ignoreLayoutSafeArea后,Row组件基于Stack内容区、Stack组件级安全区,取其右下部分并撑满可用空间。 563 564```ts 565import { LengthMetrics } from '@kit.ArkUI' 566 567@Entry 568@Component 569struct IgnoreLayoutSafeAreaTest2 { 570 build() { 571 Column() { 572 Stack() { 573 Row() 574 .backgroundColor('rgb(39, 135, 217)') 575 .width(LayoutPolicy.matchParent) // 自适应宽度 576 .height(LayoutPolicy.matchParent) // 自适应高度 577 .ignoreLayoutSafeArea([LayoutSafeAreaType.SYSTEM], [LayoutSafeAreaEdge.END, LayoutSafeAreaEdge.BOTTOM]) // 设置布局区域延伸取右和下方向,至系统避让区SYSTEM 578 579 Row() 580 .backgroundColor('rgb(0, 74, 175)') 581 .width(LayoutPolicy.matchParent) 582 .height(LayoutPolicy.matchParent) 583 584 } 585 .width(200) 586 .height(200) 587 .backgroundColor(Color.Gray) 588 .align(Alignment.TopStart) // 子组件相对于Stack容器左上对齐 589 .padding(10) // 设置10vp普通内边距 590 .safeAreaPadding(LengthMetrics.vp(10)) // 设置10vp安全区内边距(即组件级安全区) 591 } 592 .width("100%") 593 } 594} 595``` 596 597 598### 示例10(expandSafeArea与ignoreLayoutSafeArea的区别) 599 600该示例展示了容器分别设置了expandSafeArea和ignoreLayoutSafeArea的布局效果和各自对子组件布局效果的影响。两种设置下,容器都可见地进行了延伸,但前者的子组件不受延伸影响,后者的子组件因父容器的延伸改变了位置。 601 602```ts 603import { LengthMetrics } from '@kit.ArkUI' 604 605@Entry 606@Component 607struct IgnoreLayoutSafeAreaTest3 { 608 build() { 609 Row(){ 610 Column(){ 611 Stack(){ 612 Stack(){ 613 614 } 615 .width(30) 616 .height(30) 617 .backgroundColor('rgb(0, 74, 175)') 618 } 619 .width(100) 620 .height(100) 621 .backgroundColor('rgb(39, 135, 217)') 622 .align(Alignment.TopStart) 623 624 Text("基准效果").fontColor(Color.White) 625 } 626 627 Column(){ 628 Stack(){ 629 Stack(){ 630 631 } 632 .width(30) 633 .height(30) 634 .backgroundColor('rgb(0, 74, 175)') 635 } 636 .width(100) 637 .height(100) 638 .backgroundColor('rgb(39, 135, 217)') 639 .align(Alignment.TopStart) 640 .expandSafeArea() // 设置绘制区域延伸,自身绘制区域上抬,子组件相对屏幕位置不变 641 642 Text("expandSafeArea").fontColor(Color.White) 643 } 644 645 Column(){ 646 Stack(){ 647 Stack(){ 648 649 } 650 .width(30) 651 .height(30) 652 .backgroundColor('rgb(0, 74, 175)') 653 } 654 .width(100) 655 .height(100) 656 .backgroundColor('rgb(39, 135, 217)') 657 .align(Alignment.TopStart) 658 .ignoreLayoutSafeArea() // 设置布局区域延伸,自身布局区域上抬,子组件相对容器位置不变 659 660 Text("ignoreLayoutSafeArea").fontColor(Color.White) 661 } 662 } 663 .width("100%") 664 .backgroundColor(Color.Gray) 665 .justifyContent(FlexAlign.SpaceEvenly) 666 } 667} 668``` 669