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