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