• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
1920
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| ![](figures/foldsplitcontainer-1.png) | ![](figures/foldsplitcontainer-2.png) | ![](figures/foldsplitcontainer-3.png) |
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| ![](figures/foldsplitcontainer-4.png) | ![](figures/foldsplitcontainer-5.png) | ![](figures/foldsplitcontainer-6.png) |
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| ![](figures/foldsplitcontainer-7.png) | ![](figures/foldsplitcontainer-8.png) | ![](figures/foldsplitcontainer-11.png) |
674|                                       | ![](figures/foldsplitcontainer-9.png) | ![](figures/foldsplitcontainer-12.png) |
675|                                       | ![](figures/foldsplitcontainer-10.png) | ![](figures/foldsplitcontainer-13.png) |
676