1# FoldSplitContainer 2 3 4FoldSplitContainer分栏布局,实现折叠屏二分栏、三分栏在展开态、悬停态以及折叠态的区域控制。 5 6 7> **说明:** 8> 9> 该组件从API version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 10> 11> 该组件不支持在Wearable设备上使用。 12 13## 导入模块 14 15```ts 16import { FoldSplitContainer } from '@kit.ArkUI'; 17``` 18 19## 子组件 20 21无 22 23## FoldSplitContainer 24 25FoldSplitContainer({ 26 primary: Callback<void>, 27 secondary: Callback<void>, 28 extra?: Callback<void>, 29 expandedLayoutOptions: ExpandedRegionLayoutOptions, 30 hoverModeLayoutOptions: HoverModeRegionLayoutOptions, 31 foldedLayoutOptions: FoldedRegionLayoutOptions, 32 animationOptions?: AnimateParam, 33 onHoverStatusChange?: OnHoverStatusChangeHandler 34}) 35 36实现折叠屏二分栏、三分栏在展开态、悬停态以及折叠态的区域控制的分栏布局。 37 38**装饰器类型:**\@Component 39 40**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 41 42**系统能力:** SystemCapability.ArkUI.ArkUI.Full 43 44| 名称 | 类型 | 必填 | 装饰器类型 | 说明 | 45| -------- | -------- | -------- | -------- | -------- | 46| primary | ()=>void | 是 | @BuilderParam | 主要区域回调函数。 | 47| secondary | ()=>void | 是 | @BuilderParam | 次要区域回调函数。 | 48| extra | ()=>void | 否 | @BuilderParam | 扩展区域回调函数,不传入的情况,没有对应区域。 | 49| expandedLayoutOptions | [ExpandedRegionLayoutOptions](#expandedregionlayoutoptions) | 是 | @Prop | 展开态布局信息。 | 50| hoverModeLayoutOptions | [HoverModeRegionLayoutOptions](#hovermoderegionlayoutoptions) | 是 | @Prop | 悬停态布局信息。 | 51| foldedLayoutOptions | [FoldedRegionLayoutOptions](#foldedregionlayoutoptions) | 是 | @Prop | 折叠态布局信息。 | 52| animationOptions | [AnimateParam](ts-explicit-animation.md#animateparam对象说明) \| null | 否 | @Prop | 设置动画效果相关的参数,null表示关闭动效。 | 53| onHoverStatusChange | [OnHoverStatusChangeHandler](#onhoverstatuschangehandler) | 否 | - | 折叠屏进入或退出悬停模式时触发的回调函数。 | 54 55## ExpandedRegionLayoutOptions 56 57展开态布局信息。 58 59**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 60 61**系统能力:** SystemCapability.ArkUI.ArkUI.Full 62 63| 名称 | 类型 | 必填 | 说明 | 64| -------- | -------- | -------- | -------- | 65| isExtraRegionPerpendicular | boolean | 否 | 扩展区域是否从上到下贯穿整个组件,当且仅当extra有效时此字段才生效。默认值:true。 | 66| verticalSplitRatio | number | 否 | 主要区域与次要区域之间的高度比例。默认值:PresetSplitRatio.LAYOUT_1V1。 | 67| horizontalSplitRatio | number | 否 | 主要区域与扩展区域之间的宽度比例,当且仅当extra有效时此字段才生效。默认值:PresetSplitRatio.LAYOUT_3V2。 | 68| extraRegionPosition | [ExtraRegionPosition](#extraregionposition) | 否 | 扩展区域的位置信息,当且仅当isExtraRegionPerpendicular = false有效时此字段才生效。默认值:ExtraRegionPosition.top。 | 69 70## HoverModeRegionLayoutOptions 71 72悬停态布局信息。 73 74**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 75 76**系统能力:** SystemCapability.ArkUI.ArkUI.Full 77 78| 名称 | 类型 | 必填 | 说明 | 79| -------- | -------- | -------- | -------- | 80| showExtraRegion | boolean | 否 | 可折叠屏幕在半折叠状态下是否显示扩展区域。默认值:false。 | 81| horizontalSplitRatio | number | 否 | 主要区域与扩展区域之间的宽度比例,当且仅当extra有效时此字段才生效。默认值:PresetSplitRatio.LAYOUT_3V2。 | 82| extraRegionPosition | [ExtraRegionPosition](#extraregionposition) | 否 | 扩展区域的位置信息,当且仅当showExtraRegion时此字段才生效。默认值:ExtraRegionPosition.top。 | 83 84> **说明:** 85> 86> 1.设备处于悬停态时,存在避让区域,布局计算需要考虑避让区域对布局的影响。 87> 2.在悬停模式下,屏幕上半部分用于显示,下半部分用于操作。 88 89## FoldedRegionLayoutOptions 90 91折叠态布局信息。 92 93**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 94 95**系统能力:** SystemCapability.ArkUI.ArkUI.Full 96 97| 名称 | 类型 | 必填 | 说明 | 98| -------- | -------- | -------- | -------- | 99| verticalSplitRatio | number | 否 | 主要区域与次要区域之间的高度比例。默认值:PresetSplitRatio.LAYOUT_1V1。 | 100 101## OnHoverStatusChangeHandler 102 103type OnHoverStatusChangeHandler = (status: HoverModeStatus) => void 104 105onHoverStatusChange事件处理。 106 107**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 108 109**系统能力:** SystemCapability.ArkUI.ArkUI.Full 110 111**参数:** 112 113| 参数名 | 类型 | 必填 | 说明 | 114| -------- | -------- | -------- | -------- | 115| status | [HoverModeStatus](#hovermodestatus) | 是 | 折叠屏进入或退出悬停模式时触发的回调函数。 | 116 117## HoverModeStatus 118 119设备或应用的折叠、旋转、窗口状态信息。 120 121**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 122 123**系统能力:** SystemCapability.ArkUI.ArkUI.Full 124 125| 名称 | 类型 | 必填 | 说明 | 126| -------- | -------- | -------- | -------- | 127| foldStatus | [display.FoldStatus](../js-apis-display.md#foldstatus10) | 是 | 设备的折叠状态。 | 128| isHoverMode | boolean | 是 | app当前是否处于悬停态。 | 129| appRotation | number | 是 | 应用旋转角度。 | 130| windowStatusType | [window.WindowStatusType](../js-apis-window.md#windowstatustype11) | 是 | 窗口模式。 | 131 132## ExtraRegionPosition 133 134扩展区域位置信息。 135 136**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 137 138**系统能力:** SystemCapability.ArkUI.ArkUI.Full 139 140| 名称 | 值 | 说明 | 141| -------- | -------- | -------- | 142| TOP | 1 | 扩展区域在组件上半区域。 | 143| BOTTOM | 2 | 扩展区域在组件下半区域。 | 144 145## PresetSplitRatio 146 147区域比例。 148 149**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 150 151**系统能力:** SystemCapability.ArkUI.ArkUI.Full 152 153| 名称 | 值 | 说明 | 154| -------- | -------- | -------- | 155| LAYOUT_1V1 | 1 | 1:1比例。 | 156| LAYOUT_3V2 | 1.5 | 3:2比例。 | 157| LAYOUT_2V3 | 0.6666666666666666 | 2:3比例。 | 158 159## 示例 160 161### 示例1(设置二分栏) 162 163该示例实现了折叠屏二分栏在展开态、悬停态以及折叠态的区域控制。 164 165```ts 166import { FoldSplitContainer } from '@kit.ArkUI'; 167 168@Entry 169@Component 170struct TwoColumns { 171 @Builder 172 privateRegion() { 173 Text("Primary") 174 .backgroundColor('rgba(255, 0, 0, 0.1)') 175 .fontSize(28) 176 .textAlign(TextAlign.Center) 177 .height('100%') 178 .width('100%') 179 } 180 181 @Builder 182 secondaryRegion() { 183 Text("Secondary") 184 .backgroundColor('rgba(0, 255, 0, 0.1)') 185 .fontSize(28) 186 .textAlign(TextAlign.Center) 187 .height('100%') 188 .width('100%') 189 } 190 191 build() { 192 RelativeContainer() { 193 FoldSplitContainer({ 194 primary: () => { 195 this.privateRegion() 196 }, 197 secondary: () => { 198 this.secondaryRegion() 199 } 200 }) 201 } 202 .height('100%') 203 .width('100%') 204 } 205} 206``` 207 208| 折叠态 | 展开态 | 悬停态 | 209| ----- | ------ | ------ | 210|  |  |  | 211 212### 示例2(设置三分栏) 213 214该示例实现了折叠屏三分栏在展开态、悬停态以及折叠态的区域控制。 215 216```ts 217import { FoldSplitContainer } from '@kit.ArkUI'; 218 219@Entry 220@Component 221struct ThreeColumns { 222 @Builder 223 privateRegion() { 224 Text("Primary") 225 .backgroundColor('rgba(255, 0, 0, 0.1)') 226 .fontSize(28) 227 .textAlign(TextAlign.Center) 228 .height('100%') 229 .width('100%') 230 } 231 232 @Builder 233 secondaryRegion() { 234 Text("Secondary") 235 .backgroundColor('rgba(0, 255, 0, 0.1)') 236 .fontSize(28) 237 .textAlign(TextAlign.Center) 238 .height('100%') 239 .width('100%') 240 } 241 242 @Builder 243 extraRegion() { 244 Text("Extra") 245 .backgroundColor('rgba(0, 0, 255, 0.1)') 246 .fontSize(28) 247 .textAlign(TextAlign.Center) 248 .height('100%') 249 .width('100%') 250 } 251 252 build() { 253 RelativeContainer() { 254 FoldSplitContainer({ 255 primary: () => { 256 this.privateRegion() 257 }, 258 secondary: () => { 259 this.secondaryRegion() 260 }, 261 extra: () => { 262 this.extraRegion() 263 } 264 }) 265 } 266 .height('100%') 267 .width('100%') 268 } 269} 270``` 271 272| 折叠态 | 展开态 | 悬停态 | 273| ----- | ------ | ------ | 274|  |  |  | 275 276### 示例3(展开态布局信息) 277 278该示例通过配置ExpandedRegionLayoutOptions实现折叠屏展开态的布局信息。 279 280```ts 281import { 282 FoldSplitContainer, 283 PresetSplitRatio, 284 ExtraRegionPosition, 285 ExpandedRegionLayoutOptions, 286 HoverModeRegionLayoutOptions, 287 FoldedRegionLayoutOptions 288} from '@kit.ArkUI'; 289 290@Component 291struct Region { 292 @Prop title: string; 293 @BuilderParam content: () => void; 294 @Prop compBackgroundColor: string; 295 296 build() { 297 Column({ space: 8 }) { 298 Text(this.title) 299 .fontSize("24fp") 300 .fontWeight(600) 301 302 Scroll() { 303 this.content() 304 } 305 .layoutWeight(1) 306 .width("100%") 307 } 308 .backgroundColor(this.compBackgroundColor) 309 .width("100%") 310 .height("100%") 311 .padding(12) 312 } 313} 314 315const noop = () => { 316}; 317 318@Component 319struct SwitchOption { 320 @Prop label: string = "" 321 @Prop value: boolean = false 322 public onChange: (checked: boolean) => void = noop; 323 324 build() { 325 Row() { 326 Text(this.label) 327 Blank() 328 Toggle({ type: ToggleType.Switch, isOn: this.value }) 329 .onChange((isOn) => { 330 this.onChange(isOn); 331 }) 332 } 333 .backgroundColor(Color.White) 334 .borderRadius(8) 335 .padding(8) 336 .width("100%") 337 } 338} 339 340interface RadioOptions { 341 label: string; 342 value: Object | undefined | null; 343 onChecked: () => void; 344} 345 346@Component 347struct RadioOption { 348 @Prop label: string; 349 @Prop value: Object | undefined | null; 350 @Prop options: Array<RadioOptions>; 351 352 build() { 353 Row() { 354 Text(this.label) 355 Blank() 356 Column({ space: 4 }) { 357 ForEach(this.options, (option: RadioOptions) => { 358 Row() { 359 Radio({ 360 group: this.label, 361 value: JSON.stringify(option.value), 362 }) 363 .checked(this.value === option.value) 364 .onChange((checked) => { 365 if (checked) { 366 option.onChecked(); 367 } 368 }) 369 Text(option.label) 370 } 371 }) 372 } 373 .alignItems(HorizontalAlign.Start) 374 } 375 .alignItems(VerticalAlign.Top) 376 .backgroundColor(Color.White) 377 .borderRadius(8) 378 .padding(8) 379 .width("100%") 380 } 381} 382 383@Entry 384@Component 385struct Index { 386 @State expandedRegionLayoutOptions: ExpandedRegionLayoutOptions = { 387 horizontalSplitRatio: PresetSplitRatio.LAYOUT_3V2, 388 verticalSplitRatio: PresetSplitRatio.LAYOUT_1V1, 389 isExtraRegionPerpendicular: true, 390 extraRegionPosition: ExtraRegionPosition.TOP 391 }; 392 @State foldingRegionLayoutOptions: HoverModeRegionLayoutOptions = { 393 horizontalSplitRatio: PresetSplitRatio.LAYOUT_3V2, 394 showExtraRegion: false, 395 extraRegionPosition: ExtraRegionPosition.TOP 396 }; 397 @State foldedRegionLayoutOptions: FoldedRegionLayoutOptions = { 398 verticalSplitRatio: PresetSplitRatio.LAYOUT_1V1 399 }; 400 401 @Builder 402 MajorRegion() { 403 Region({ 404 title: "折叠态配置", 405 compBackgroundColor: "rgba(255, 0, 0, 0.1)", 406 }) { 407 Column({ space: 4 }) { 408 RadioOption({ 409 label: "折叠态垂直高度度比", 410 value: this.foldedRegionLayoutOptions.verticalSplitRatio, 411 options: [ 412 { 413 label: "1:1", 414 value: PresetSplitRatio.LAYOUT_1V1, 415 onChecked: () => { 416 this.foldedRegionLayoutOptions.verticalSplitRatio = PresetSplitRatio.LAYOUT_1V1 417 } 418 }, 419 { 420 label: "2:3", 421 value: PresetSplitRatio.LAYOUT_2V3, 422 onChecked: () => { 423 this.foldedRegionLayoutOptions.verticalSplitRatio = PresetSplitRatio.LAYOUT_2V3 424 } 425 }, 426 { 427 label: "3:2", 428 value: PresetSplitRatio.LAYOUT_3V2, 429 onChecked: () => { 430 this.foldedRegionLayoutOptions.verticalSplitRatio = PresetSplitRatio.LAYOUT_3V2 431 } 432 }, 433 { 434 label: "未定义", 435 value: undefined, 436 onChecked: () => { 437 this.foldedRegionLayoutOptions.verticalSplitRatio = undefined 438 } 439 } 440 ] 441 }) 442 } 443 .constraintSize({ minHeight: "100%" }) 444 } 445 } 446 447 @Builder 448 MinorRegion() { 449 Region({ 450 title: "悬停态配置", 451 compBackgroundColor: "rgba(0, 255, 0, 0.1)" 452 }) { 453 Column({ space: 4 }) { 454 RadioOption({ 455 label: "悬停态水平宽度比", 456 value: this.foldingRegionLayoutOptions.horizontalSplitRatio, 457 options: [ 458 { 459 label: "1:1", 460 value: PresetSplitRatio.LAYOUT_1V1, 461 onChecked: () => { 462 this.foldingRegionLayoutOptions.horizontalSplitRatio = PresetSplitRatio.LAYOUT_1V1 463 } 464 }, 465 { 466 label: "2:3", 467 value: PresetSplitRatio.LAYOUT_2V3, 468 onChecked: () => { 469 this.foldingRegionLayoutOptions.horizontalSplitRatio = PresetSplitRatio.LAYOUT_2V3 470 } 471 }, 472 { 473 label: "3:2", 474 value: PresetSplitRatio.LAYOUT_3V2, 475 onChecked: () => { 476 this.foldingRegionLayoutOptions.horizontalSplitRatio = PresetSplitRatio.LAYOUT_3V2 477 } 478 }, 479 { 480 label: "未定义", 481 value: undefined, 482 onChecked: () => { 483 this.foldingRegionLayoutOptions.horizontalSplitRatio = undefined 484 } 485 }, 486 ] 487 }) 488 489 SwitchOption({ 490 label: "悬停态是否显示扩展区", 491 value: this.foldingRegionLayoutOptions.showExtraRegion, 492 onChange: (checked) => { 493 this.foldingRegionLayoutOptions.showExtraRegion = checked; 494 } 495 }) 496 497 if (this.foldingRegionLayoutOptions.showExtraRegion) { 498 RadioOption({ 499 label: "悬停态扩展区位置", 500 value: this.foldingRegionLayoutOptions.extraRegionPosition, 501 options: [ 502 { 503 label: "顶部", 504 value: ExtraRegionPosition.TOP, 505 onChecked: () => { 506 this.foldingRegionLayoutOptions.extraRegionPosition = ExtraRegionPosition.TOP 507 } 508 }, 509 { 510 label: "底部", 511 value: ExtraRegionPosition.BOTTOM, 512 onChecked: () => { 513 this.foldingRegionLayoutOptions.extraRegionPosition = ExtraRegionPosition.BOTTOM 514 } 515 }, 516 { 517 label: "未定义", 518 value: undefined, 519 onChecked: () => { 520 this.foldingRegionLayoutOptions.extraRegionPosition = undefined 521 } 522 }, 523 ] 524 }) 525 } 526 } 527 .constraintSize({ minHeight: "100%" }) 528 } 529 } 530 531 @Builder 532 ExtraRegion() { 533 Region({ 534 title: "展开态配置", 535 compBackgroundColor: "rgba(0, 0, 255, 0.1)" 536 }) { 537 Column({ space: 4 }) { 538 RadioOption({ 539 label: "展开态水平宽度比", 540 value: this.expandedRegionLayoutOptions.horizontalSplitRatio, 541 options: [ 542 { 543 label: "1:1", 544 value: PresetSplitRatio.LAYOUT_1V1, 545 onChecked: () => { 546 this.expandedRegionLayoutOptions.horizontalSplitRatio = PresetSplitRatio.LAYOUT_1V1 547 } 548 }, 549 { 550 label: "2:3", 551 value: PresetSplitRatio.LAYOUT_2V3, 552 onChecked: () => { 553 this.expandedRegionLayoutOptions.horizontalSplitRatio = PresetSplitRatio.LAYOUT_2V3 554 } 555 }, 556 { 557 label: "3:2", 558 value: PresetSplitRatio.LAYOUT_3V2, 559 onChecked: () => { 560 this.expandedRegionLayoutOptions.horizontalSplitRatio = PresetSplitRatio.LAYOUT_3V2 561 } 562 }, 563 { 564 label: "未定义", 565 value: undefined, 566 onChecked: () => { 567 this.expandedRegionLayoutOptions.horizontalSplitRatio = undefined 568 } 569 }, 570 ] 571 }) 572 573 RadioOption({ 574 label: "展开态垂直高度度比", 575 value: this.expandedRegionLayoutOptions.verticalSplitRatio, 576 options: [ 577 { 578 label: "1:1", 579 value: PresetSplitRatio.LAYOUT_1V1, 580 onChecked: () => { 581 this.expandedRegionLayoutOptions.verticalSplitRatio = PresetSplitRatio.LAYOUT_1V1 582 } 583 }, 584 { 585 label: "2:3", 586 value: PresetSplitRatio.LAYOUT_2V3, 587 onChecked: () => { 588 this.expandedRegionLayoutOptions.verticalSplitRatio = PresetSplitRatio.LAYOUT_2V3 589 } 590 }, 591 { 592 label: "3:2", 593 value: PresetSplitRatio.LAYOUT_3V2, 594 onChecked: () => { 595 this.expandedRegionLayoutOptions.verticalSplitRatio = PresetSplitRatio.LAYOUT_3V2 596 } 597 }, 598 { 599 label: "未定义", 600 value: undefined, 601 onChecked: () => { 602 this.expandedRegionLayoutOptions.verticalSplitRatio = undefined 603 } 604 } 605 ] 606 }) 607 608 SwitchOption({ 609 label: "展开态扩展区是否上下贯穿", 610 value: this.expandedRegionLayoutOptions.isExtraRegionPerpendicular, 611 onChange: (checked) => { 612 this.expandedRegionLayoutOptions.isExtraRegionPerpendicular = checked; 613 } 614 }) 615 616 if (!this.expandedRegionLayoutOptions.isExtraRegionPerpendicular) { 617 RadioOption({ 618 label: "展开态扩展区位置", 619 value: this.expandedRegionLayoutOptions.extraRegionPosition, 620 options: [ 621 { 622 label: "顶部", 623 value: ExtraRegionPosition.TOP, 624 onChecked: () => { 625 this.expandedRegionLayoutOptions.extraRegionPosition = ExtraRegionPosition.TOP 626 } 627 }, 628 { 629 label: "底部", 630 value: ExtraRegionPosition.BOTTOM, 631 onChecked: () => { 632 this.expandedRegionLayoutOptions.extraRegionPosition = ExtraRegionPosition.BOTTOM 633 } 634 }, 635 { 636 label: "未定义", 637 value: undefined, 638 onChecked: () => { 639 this.expandedRegionLayoutOptions.extraRegionPosition = undefined 640 } 641 }, 642 ] 643 }) 644 } 645 } 646 .constraintSize({ minHeight: "100%" }) 647 } 648 } 649 650 build() { 651 Column() { 652 FoldSplitContainer({ 653 primary: () => { 654 this.MajorRegion() 655 }, 656 secondary: () => { 657 this.MinorRegion() 658 }, 659 extra: () => { 660 this.ExtraRegion() 661 }, 662 expandedLayoutOptions: this.expandedRegionLayoutOptions, 663 hoverModeLayoutOptions: this.foldingRegionLayoutOptions, 664 foldedLayoutOptions: this.foldedRegionLayoutOptions, 665 }) 666 } 667 .width("100%") 668 .height("100%") 669 } 670} 671``` 672 673| 折叠态 | 展开态 | 悬停态 | 674| ----- | ------ | ------ | 675|  |  |  | 676| |  |  | 677| |  |  | 678