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