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