• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 自适应布局
2
3
4针对常见的开发场景,方舟开发框架提炼了七种自适应布局能力,这些布局可以独立使用,也可多种布局叠加使用。
5
6
7  | 自适应布局类别 | 自适应布局能力 | 使用场景 | 实现方式 |
8| -------- | -------- | -------- | -------- |
9| 自适应拉伸 | [拉伸能力](#拉伸能力) | 容器组件尺寸发生变化时,增加或减小的空间**全部分配**给容器组件内**指定区域**。 | [Flex布局](../../reference/arkui-ts/ts-universal-attributes-flex-layout.md)的flexGrow和flexShrink属性 |
10|  | [均分能力](#均分能力) | 容器组件尺寸发生变化时,增加或减小的空间**均匀分配**给容器组件内**所有空白区域**。 | [Row组件](../../reference/arkui-ts/ts-container-row.md)、[Column组件](../../reference/arkui-ts/ts-container-column.md)或[Flex组件](../../reference/arkui-ts/ts-container-flex.md)的justifyContent属性设置为FlexAlign.SpaceEvenly |
11| 自适应缩放 | [占比能力](#占比能力) | 子组件的宽或高**按照预设的比例**,随容器组件发生变化。 | 基于通用属性的两种实现方式:<br/>-&nbsp;将子组件的宽高设置为父组件宽高的百分比<br/>-&nbsp;layoutWeight属性 |
12|  | [缩放能力](#缩放能力) | 子组件的宽高**按照预设的比例**,随容器组件发生变化,且变化过程中子组件的**宽高比不变**。 | [布局约束](../../reference/arkui-ts/ts-universal-attributes-layout-constraints.md)的aspectRatio属性 |
13| 自适应延伸 | [延伸能力](#延伸能力) | 容器组件内的子组件,按照其**在列表中的先后顺序**,随容器组件尺寸变化显示或隐藏。 | 基于容器组件的两种实现方式:<br/>-&nbsp;通过[List组件](../../reference/arkui-ts/ts-container-list.md)实现<br/>-&nbsp;通过[Scroll组件](../../reference/arkui-ts/ts-container-scroll.md)配合[Row组件](../../reference/arkui-ts/ts-container-row.md)或[Column组件](../../reference/arkui-ts/ts-container-column.md)实现 |
14|  | [隐藏能力](#隐藏能力) | 容器组件内的子组件,按照其**预设的显示优先级**,随容器组件尺寸变化显示或隐藏。**相同显示优先级的子组件同时显示或隐藏**。 | [布局约束](../../reference/arkui-ts/ts-universal-attributes-layout-constraints.md)的displayPriority属性 |
15| 自适应折行 | [折行能力](#折行能力) | 容器组件尺寸发生变化时,如果布局方向尺寸不足以显示完整内容,**自动换行**。 | [Flex组件](../../reference/arkui-ts/ts-container-flex.md)的wrap属性设置为FlexWrap.Wrap |
16
17
18下面我们依次介绍这几种自适应布局能力。
19
20
21## 拉伸能力
22
23
24拉伸能力是指容器组件尺寸发生变化时,增加或减小的空间全部分配给容器组件内指定区域。
25
26
27拉伸能力通常通过[Flex布局](../../reference/arkui-ts/ts-universal-attributes-flex-layout.md)中的flexGrow和flexShrink属性实现,flexGrow和flexShink属性常与flexBasis属性搭配使用,故将这三个属性放在一起介绍。
28
29
30  | 属性 | 类型 | 默认值 | 描述 |
31| -------- | -------- | -------- | -------- |
32| flexGrow | number | 0 | 仅当父容器宽度大于所有子组件宽度的总和时,该属性生效。配置了此属性的子组件,按照比例拉伸,分配父容器的多余空间。 |
33| flexShrink | number | 1 | 仅当父容器宽度小于所有子组件宽度的总和时,该属性生效。配置了此属性的子组件,按照比例收缩,分配父容器的不足空间。 |
34| flexBasis | 'auto'&nbsp;\|&nbsp;[Length](../../reference/arkui-ts/ts-types.md#length) | 'auto' | 设置组件在Flex容器中主轴方向上基准尺寸。'auto'意味着使用组件原始的尺寸,不做修改。<br/>flexBasis属性不是必须的,通过width或height也可以达到同样的效果。当flexBasis属性与width或height发生冲突时,以flexBasis属性为准。 |
35
36
37> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
38> - 开发者期望将父容器的剩余空间全部分配给某空白区域时,也可以通过[Blank组件](../../reference/arkui-ts/ts-basic-components-blank.md)实现。注意仅当父组件为Row\Column\Flex组件时,Blank组件才会生效。
39>
40> - 类Web开发范式也是通过flex-grow和flex-shrink实现拉伸能力,同时也支持配置flex-basis,详见[通用样式](../../reference/arkui-js/js-components-common-styles.md)。
41>
42> - 类Web开发范式没有提供blank组件,但可以通过div组件模拟blank组件的行为,如“&lt;div style='flex-grow: 1; flex-shrink: 0; flex-basis: 0'&gt;&lt;/div&gt;”。
43
44**示例1**
45
46
47本示例中的页面由中间的内容区(包含一张图片)以及两侧的留白区组成,各区域的属性配置如下。
48
49* 中间内容区的宽度设置为400vp,同时将flexGrow属性设置为1,flexShrink属性设置为0。
50
51* 两侧留白区的宽度设置为150vp,同时将flexGrow属性设置为0,flexShrink属性设置为1。
52
53由上可知,父容器的基准尺寸是700vp(150vp+400vp+150vp)。
54
55可以通过拖动底部的滑动条改变父容器的尺寸,查看布局变化。
56
57* 当父容器的尺寸大于700vp时,父容器中多余的空间全部分配给中间内容区。
58
59* 当父容器的尺寸小于700vp时,左右两侧的留白区按照“1:1”的比例收缩(即平均分配父容器的不足空间)。
60
61
62![zh-cn_image_0000001335796258](figures/zh-cn_image_0000001335796258.gif)
63
64
65
66```
67@Entry
68@Component
69struct FlexibleCapabilitySample1 {
70  @State containerWidth: number = 402
71
72  // 底部滑块,可以通过拖拽滑块改变容器尺寸。
73  @Builder slider() {
74    Slider({ value: this.containerWidth, min: 402, max: 1000, style: SliderStyle.OutSet })
75      .blockColor(Color.White)
76      .width('60%')
77      .onChange((value: number) => {
78        this.containerWidth = value;
79      })
80      .position({ x: '20%', y: '80%' })
81  }
82
83  build() {
84    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center,
85      alignItems: ItemAlign.Center }) {
86      Column() {
87        Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Center,
88          alignItems: ItemAlign.Center }) {
89          // 通过flexGrow和flexShink属性,将多余的空间全部分配给图片,将不足的控件全部分配给两侧空白区域。
90          Row().width(150).height(400).backgroundColor('#FFFFFF')
91            .flexGrow(0).flexShrink(1)
92          Image($r("app.media.illustrator")).width(400).height(400)
93            .objectFit(ImageFit.Contain)
94            .backgroundColor("#66F1CCB8")
95            .flexGrow(1).flexShrink(0)
96          Row().width(150).height(400).backgroundColor('#FFFFFF')
97            .flexGrow(0).flexShrink(1)
98        }.width(this.containerWidth)
99      }
100
101      this.slider()
102    }.width('100%').height('100%').backgroundColor('#F1F3F5')
103  }
104}
105```
106
107**示例2**
108
109
110文字和开关的尺寸固定,仅有中间空白区域(Blank组件)随父容器尺寸变化而伸缩。
111
112
113![zh-cn_image_0000001335316714](figures/zh-cn_image_0000001335316714.gif)
114
115
116
117```
118@Entry
119@Component
120struct FlexibleCapabilitySample2 {
121  @State rate: number = 0.8
122
123  // 底部滑块,可以通过拖拽滑块改变容器尺寸
124  @Builder slider() {
125    Slider({ value: this.rate * 100, min: 30, max: 80, style: SliderStyle.OutSet })
126      .blockColor(Color.White)
127      .width('60%')
128      .onChange((value: number) => {
129        this.rate = value / 100;
130      })
131      .position({ x: '20%', y: '80%' })
132  }
133
134  build() {
135    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center,
136      alignItems: ItemAlign.Center }) {
137      Column() {
138        Row() {
139          Text('飞行模式')
140            .fontSize(16)
141            .width(135)
142            .height(22)
143            .fontWeight(FontWeight.Medium)
144            .lineHeight(22)
145          Blank()      // 通过Blank组件实现拉伸能力
146          Toggle({ type: ToggleType.Switch })
147            .width(36)
148            .height(20)
149        }
150        .height(55)
151        .borderRadius(12)
152        .padding({ left: 13, right: 13 })
153        .backgroundColor('#FFFFFF')
154        .width(this.rate * 100 + '%')
155      }
156
157      this.slider()
158    }.width('100%').height('100%').backgroundColor('#F1F3F5')
159  }
160}
161```
162
163
164## 均分能力
165
166
167均分能力是指容器组件尺寸发生变化时,增加或减小的空间均匀分配给容器组件内所有空白区域。它常用于内容数量固定、均分显示的场景,比如工具栏、底部菜单栏等。
168
169
170均分能力可以通过将[Row组件](../../reference/arkui-ts/ts-container-row.md)、[Column组件](../../reference/arkui-ts/ts-container-column.md)或[Flex组件](../../reference/arkui-ts/ts-container-flex.md)的justifyContent属性设置为FlexAlign.SpaceEvenly实现,即子元素在父容器主轴方向等间距布局,相邻元素之间的间距、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。
171
172
173> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
174> - 均分能力还可以通过其它方式实现,如使用[Grid网格组件](../../reference/arkui-ts/ts-container-grid.md)或在每个组件间添加Blank组件等。
175>
176> - 类Web开发范式中,通过将[div组件](../../reference/arkui-js/js-components-container-div.md)的justify-content属性设置为space-evenly来实现均分布局。
177
178
179**示例:**
180
181
182父容器尺寸变化过程中,图标及文字的尺寸不变,图标间的间距及图标离左右边缘的距离同时均等改变。
183
184
185![zh-cn_image_0000001335477142](figures/zh-cn_image_0000001335477142.gif)
186
187
188
189```
190@Entry
191@Component
192struct EquipartitionCapabilitySample {
193  const list: number [] = [0, 1, 2, 3]
194  @State rate: number = 0.6
195
196  // 底部滑块,可以通过拖拽滑块改变容器尺寸
197  @Builder slider() {
198    Slider({ value: this.rate * 100, min: 30, max: 60, style: SliderStyle.OutSet })
199      .blockColor(Color.White)
200      .width('60%')
201      .onChange((value: number) => {
202        this.rate = value / 100
203      })
204      .position({ x: '20%', y: '80%' })
205  }
206
207  build() {
208    Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
209      Column() {
210        // 均匀分配父容器主轴方向的剩余空间
211        Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
212          ForEach(this.list, (item) => {
213            Column() {
214              Image($r("app.media.icon")).width(48).height(48).margin({ top: 8 })
215              Text('App name')
216                .width(64)
217                .height(30)
218                .lineHeight(15)
219                .fontSize(12)
220                .textAlign(TextAlign.Center)
221                .margin({ top: 8 })
222                .padding({ bottom: 15 })
223            }.width(80).height(102)
224          })
225        }
226        // 均匀分配父容器主轴方向的剩余空间
227        Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
228          ForEach(this.list, (item) => {
229            Column() {
230              Image($r("app.media.icon")).width(48).height(48).margin({ top: 8 })
231              Text('App name')
232                .width(64)
233                .height(30)
234                .lineHeight(15)
235                .fontSize(12)
236                .textAlign(TextAlign.Center)
237                .margin({ top: 8 })
238                .padding({ bottom: 15 })
239            }.width(80).height(102)
240          })
241        }
242      }
243      .width(this.rate * 100 + '%')
244      .height(222)
245      .padding({ top: 16 })
246      .backgroundColor('#FFFFFF')
247      .borderRadius(16)
248
249      this.slider()
250    }
251    .width('100%')
252    .height('100%')
253    .backgroundColor('#F1F3F5')
254  }
255}
256```
257
258
259## 占比能力
260
261
262占比能力是指子组件的宽高按照预设的比例,随父容器组件发生变化。
263
264
265占比能力通常有两种实现方式:
266
267
268- 将子组件的宽高设置为父组件宽高的百分比,详见[尺寸设置](../../reference/arkui-ts/ts-universal-attributes-size.md)及[长度类型](../../reference/arkui-ts/ts-types.md#length)。
269
270- 通过layoutWeight属性配置互为兄弟关系的组件在父容器主轴方向的布局权重,详见[尺寸设置](../../reference/arkui-ts/ts-universal-attributes-size.md)。
271  - 当父容器尺寸确定时,其子组件按照开发者配置的权重比例分配父容器中主轴方向的空间。
272  - 仅当父容器是Row、Colomn或者Flex时,layoutWeight属性才会生效。
273  - 设置layoutWeight属性后,组件本身的尺寸会失效。比如同时设置了.width('40%')和.layoutWeight(1),那么只有.layoutWeight(1)会生效。
274
275
276layoutWeight存在使用限制,所以实际使用过程中大多通过将子组件宽高设置为父组件的百分比来实现占比能力。
277
278
279> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
280> - 占比能力在实际开发中使用的非常广泛,可以通过很多不同的方式实现占比能力,如还可以通过[Grid组件](../../reference/arkui-ts/ts-container-grid.md)的columnsTemplate属性设置网格容器中列的数量及其宽度比例,或通过配置子组件在栅格(本章后文将详细介绍栅格系统)中占据不同的列数来实现占比能力。本小节仅介绍最基础和常用的实现方式,局限性较大或比非常小众的实现方式,本文不做展开介绍。
281>
282> - 类Web开发范式同样支持以百分比的形式设置组件的宽高,详见[通用样式](../../reference/arkui-js/js-components-common-styles.md)中关于width和height的介绍以及[长度类型介绍](../../reference/arkui-js/js-appendix-types.md#长度类型)。
283>
284> - 与声明式开发范式中的layoutWeight属性类似,类Web开发范式提供了[flex-weight样式](../../reference/arkui-js/js-components-common-atomic-layout.md#占比能力)用于配置互为兄弟关系的组件在父容器主轴方向的布局权重。
285
286
287**示例:**
288
289
290简单的播放控制栏,其中“上一首”、“播放/暂停”、“下一首”的layoutWeight属性都设置为1,因此它们按照“1:1:1”的比例均分父容器主轴方向的空间。
291
292
293将三个按钮的.layoutWeight(1)分别替换为.width('33%')、.width('34%')、.width('33%'),也可以实现与当前同样的显示效果。
294
295
296![zh-cn_image_0000001385757965](figures/zh-cn_image_0000001385757965.gif)
297
298
299
300```
301@Entry
302@Component
303struct ProportionCapabilitySample {
304  @State rate: number = 0.5
305
306  // 底部滑块,可以通过拖拽滑块改变容器尺寸
307  @Builder slider() {
308    Slider({ value: 100, min: 25, max: 50, style: SliderStyle.OutSet })
309      .blockColor(Color.White)
310      .width('60%')
311      .height(50)
312      .onChange((value: number) => {
313        this.rate = value / 100
314      })
315      .position({ x: '20%', y: '80%' })
316  }
317
318  build() {
319    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
320      Column() {
321        Row() {
322          Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
323            Image($r("app.media.down"))
324              .width(48)
325              .height(48)
326          }
327          .height(96)
328          .layoutWeight(1)  // 设置子组件在父容器主轴方向的布局权重
329
330          Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
331            Image($r("app.media.pause"))
332              .width(48)
333              .height(48)
334          }
335          .height(96)
336          .layoutWeight(1)  // 设置子组件在父容器主轴方向的布局权重
337          .backgroundColor('#66F1CCB8')
338
339          Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
340            Image($r("app.media.next"))
341              .width(48)
342              .height(48)
343          }
344          .height(96)
345          .layoutWeight(1)  // 设置子组件在父容器主轴方向的布局权重
346        }
347        .width(this.rate * 100 + '%')
348        .height(96)
349        .borderRadius(16)
350        .backgroundColor('#FFFFFF')
351      }
352
353      this.slider()
354    }
355    .width('100%')
356    .height('100%')
357    .backgroundColor('#F1F3F5')
358  }
359}
360```
361
362
363
364## 缩放能力
365
366
367缩放能力是指子组件的宽高按照预设的比例,随容器组件发生变化,且变化过程中子组件的宽高比不变。
368
369
370缩放能力通过使用百分比布局配合**固定宽高比**(aspectRatio属性)实现当容器尺寸发生变化时,内容自适应调整。
371
372
373可以访问[布局约束](../../reference/arkui-ts/ts-universal-attributes-layout-constraints.md),了解aspectRatio属性的详细信息。
374
375
376> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
377> 类Web开发范式同样提供了[aspect-ratio样式](../../reference/arkui-js/js-components-common-atomic-layout.md#固定比例),用于固定组件的宽高比。
378
379
380**示例:**
381
382
383为方便查看效果,示例中特意给Column组件加了边框。可以看到Column组件随着其Flex父组件尺寸变化而缩放的过程中,始终保持预设的宽高比,其中的图片也始终正常显示。
384
385
386![zh-cn_image_0000001335640862](figures/zh-cn_image_0000001335640862.gif)
387
388
389
390```
391@Entry
392@Component
393struct ScaleCapabilitySample {
394  @State sliderWidth: number = 400
395  @State sliderHeight: number = 400
396
397  // 底部滑块,可以通过拖拽滑块改变容器尺寸
398  @Builder slider() {
399    Slider({ value: this.sliderWidth, min: 100, max: 400, style: SliderStyle.OutSet })
400      .blockColor(Color.White)
401      .width('60%')
402      .height(50)
403      .onChange((value: number) => {
404        this.sliderWidth = value;
405      })
406      .position({ x: '20%', y: '80%' })
407    Slider({ value: this.sliderHeight, min: 100, max: 400, style: SliderStyle.OutSet })
408      .blockColor(Color.White)
409      .width('60%')
410      .height(50)
411      .onChange((value: number) => {
412        this.sliderHeight = value
413      })
414      .position({ x: '20%', y: '87%' })
415  }
416
417  build() {
418    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
419      Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
420        Column() {
421          Image($r("app.media.illustrator")).width('100%').height('100%')
422        }
423        .aspectRatio(1)                           // 固定宽高比
424        .border({ width: 2, color: "#66F1CCB8"})  // 边框,仅用于展示效果
425      }
426      .backgroundColor("#FFFFFF")
427      .height(this.sliderWidth)
428      .width(this.sliderHeight)
429
430      this.slider()
431    }.width('100%')
432    .height('100%')
433    .backgroundColor("#F1F3F5")
434  }
435}
436```
437
438
439## 延伸能力
440
441
442延伸能力是指容器组件内的子组件,按照其在列表中的先后顺序,随容器组件尺寸变化显示或隐藏。它可以根据显示区域的尺寸,显示不同数量的元素。
443
444
445延伸能力通常有两种实现方式:
446
447
448- 通过[List组件](../../reference/arkui-ts/ts-container-list.md)实现。
449
450- 通过[Scroll组件](../../reference/arkui-ts/ts-container-scroll.md)配合[Row组件](../../reference/arkui-ts/ts-container-row.md)或[Column组件](../../reference/arkui-ts/ts-container-column.md)实现。
451
452
453> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
454> - List、Row或Column组件中子节点的在页面显示时就已经全部完成了布局计算及渲染,只不过受限于父容器尺寸,用户只能看到一部分。随着父容器尺寸增大,用户可以看到的子节点数目也相应的增加。用户还可以通过手指滑动触发列表滑动,查看被隐藏的子节点。
455>
456> - 类Web开发范式同样可以使用[list组件](../../reference/arkui-js/js-components-container-list.md)实现延伸能力。
457>
458> - 类Web开发范式没有提供scroll组件,但可以将[div组件](../../reference/arkui-js/js-components-container-div.md)的overflow样式设置为scroll(即div组件主轴方向上子元素的尺寸超过div组件本身的尺寸时进行滚动显示)来模拟scroll组件的行为。
459
460
461**示例:**
462
463
464当父容器的尺寸发生改变时,页面中显示的图标数量随之发生改变。
465
466
467分别通过List组件实现及通过Scroll组件配合Row组件实现。
468
469
470![zh-cn_image_0000001335641246](figures/zh-cn_image_0000001335641246.gif)
471
472
473(1)通过List组件实现。
474
475
476
477```
478@Entry
479@Component
480struct ExtensionCapabilitySample1 {
481  @State rate: number = 0.60
482  const appList: number [] = [0, 1, 2, 3, 4, 5, 6, 7]
483
484  // 底部滑块,可以通过拖拽滑块改变容器尺寸
485  @Builder slider() {
486    Slider({ value: this.rate * 100, min: 8, max: 60, style: SliderStyle.OutSet })
487      .blockColor(Color.White)
488      .width('60%')
489      .height(50)
490      .onChange((value: number) => {
491        this.rate = value / 100
492      })
493      .position({ x: '20%', y: '80%' })
494  }
495
496  build() {
497    Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
498      Row({ space: 10 }) {
499        // 通过List组件实现隐藏能力
500        List({ space: 10 }) {
501          ForEach(this.appList, (item) => {
502            ListItem() {
503              Column() {
504                Image($r("app.media.icon")).width(48).height(48).margin({ top: 8 })
505                Text('App name')
506                  .width(64)
507                  .height(30)
508                  .lineHeight(15)
509                  .fontSize(12)
510                  .textAlign(TextAlign.Center)
511                  .margin({ top: 8 })
512                  .padding({ bottom: 15 })
513              }.width(80).height(102)
514            }.width(80).height(102)
515          })
516        }
517        .padding({ top: 16, left: 10 })
518        .listDirection(Axis.Horizontal)
519        .width('100%')
520        .height(118)
521        .borderRadius(16)
522        .backgroundColor(Color.White)
523      }
524      .width(this.rate * 100 + '%')
525
526      this.slider()
527    }
528    .width('100%')
529    .height('100%')
530    .backgroundColor('#F1F3F5')
531  }
532}
533```
534
535
536  (2)通过Scroll组件配合Row组件实现。
537
538```
539@Entry
540@Component
541struct ExtensionCapabilitySample2 {
542  private scroller: Scroller = new Scroller()
543  @State rate: number = 0.60
544  @State appList: number [] = [0, 1, 2, 3, 4, 5, 6, 7]
545
546  // 底部滑块,可以通过拖拽滑块改变容器尺寸
547  @Builder slider() {
548    Slider({ value: this.rate * 100, min: 8, max: 60, style: SliderStyle.OutSet })
549      .blockColor(Color.White)
550      .width('60%')
551      .height(50)
552      .onChange((value: number) => {
553        this.rate = value / 100;
554      })
555      .position({ x: '20%', y: '80%' })
556  }
557
558  build() {
559    Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
560      // 通过Scroll和Row组件实现隐藏能力
561      Scroll(this.scroller) {
562        Row({ space: 10 }) {
563          ForEach(this.appList, () => {
564            Column() {
565              Image($r("app.media.icon")).width(48).height(48).margin({ top: 8 })
566              Text('App name')
567                .width(64)
568                .height(30)
569                .lineHeight(15)
570                .fontSize(12)
571                .textAlign(TextAlign.Center)
572                .margin({ top: 8 })
573                .padding({ bottom: 15 })
574
575
576            }.width(80).height(102)
577          })
578        }
579        .padding({ top: 16, left: 10 })
580        .height(118)
581        .borderRadius(16)
582        .backgroundColor(Color.White)
583      }
584      .scrollable(ScrollDirection.Horizontal)
585      .width(this.rate * 100 + '%')
586
587      this.slider()
588    }
589    .width('100%')
590    .height('100%')
591    .backgroundColor('#F1F3F5')
592  }
593}
594```
595
596
597
598## 隐藏能力
599
600隐藏能力是指容器组件内的子组件,按照其预设的显示优先级,随容器组件尺寸变化显示或隐藏,其中相同显示优先级的子组件同时显示或隐藏。它是一种比较高级的布局方式,常用于分辨率变化较大,且不同分辨率下显示内容有所差异的场景。主要思想是通过增加或减少显示内容,来保持最佳的显示效果。
601
602隐藏能力通过设置**布局优先级**(displayPriority属性)来控制显隐,当布局主轴方向剩余尺寸不足以满足全部元素时,按照布局优先级大小,从小到大依次隐藏,直到容器能够完整显示剩余元素。具有相同布局优先级的元素将同时显示或者隐藏。
603
604可以访问[布局约束](../../reference/arkui-ts/ts-universal-attributes-layout-constraints.md),了解displayPriority属性的详细信息。
605
606> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
607> 类Web开发范式同样支持[display-index样式](../../reference/arkui-js/js-components-common-atomic-layout.md#隐藏能力),用于设置布局优先级。
608
609**示例:**
610
611父容器尺寸发生变化时,其子元素按照预设的优先级显示或隐藏。
612
613![zh-cn_image_0000001335485154](figures/zh-cn_image_0000001335485154.gif)
614
615
616```
617@Entry
618@Component
619struct HiddenCapabilitySample {
620  @State rate: number = 0.45
621
622  // 底部滑块,可以通过拖拽滑块改变容器尺寸
623  @Builder slider() {
624    Slider({ value: this.rate * 100, min: 10, max: 45, style: SliderStyle.OutSet })
625      .blockColor(Color.White)
626      .width('60%')
627      .height(50)
628      .onChange((value: number) => {
629        this.rate = value / 100
630      })
631      .position({ x: '20%', y: '80%' })
632  }
633
634  build() {
635      Flex({ direction: FlexDirection.Column,
636        justifyContent: FlexAlign.Center,
637        alignItems: ItemAlign.Center }) {
638        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
639          Image($r("app.media.favorite"))
640            .width(48)
641            .height(48)
642            .objectFit(ImageFit.Contain)
643            .margin({ left: 12, right: 12 })
644            .displayPriority(1)  // 布局优先级
645
646          Image($r("app.media.down"))
647            .width(48)
648            .height(48)
649            .objectFit(ImageFit.Contain)
650            .margin({ left: 12, right: 12 })
651            .displayPriority(2)  // 布局优先级
652
653          Image($r("app.media.pause"))
654            .width(48)
655            .height(48)
656            .objectFit(ImageFit.Contain)
657            .margin({ left: 12, right: 12 })
658            .displayPriority(3)  // 布局优先级
659
660          Image($r("app.media.next"))
661            .width(48)
662            .height(48)
663            .objectFit(ImageFit.Contain)
664            .margin({ left: 12, right: 12 })
665            .displayPriority(2)  // 布局优先级
666
667          Image($r("app.media.list"))
668            .width(48)
669            .height(48)
670            .objectFit(ImageFit.Contain)
671            .margin({ left: 12, right: 12 })
672            .displayPriority(1)  // 布局优先级
673        }
674        .width(this.rate * 100 + '%')
675        .height(96)
676        .borderRadius(16)
677        .backgroundColor('#FFFFFF')
678
679        this.slider()
680      }
681      .width('100%')
682      .height('100%')
683      .backgroundColor('#F1F3F5')
684  }
685}
686```
687
688
689## 折行能力
690
691折行能力是指容器组件尺寸发生变化,当布局方向尺寸不足以显示完整内容时自动换行。它常用于横竖屏适配或默认设备向平板切换的场景。
692
693折行能力通过使用 **Flex折行布局** (将wrap属性设置为FlexWrap.Wrap)实现,当横向布局尺寸不足以完整显示内容元素时,通过折行的方式,将元素显示在下方。
694
695可以访问[Flex组件](../../reference/arkui-ts/ts-container-flex.md),了解Flex组件的详细用法。
696
697> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
698> 类Web开发范式通过将[div组件](../../reference/arkui-js/js-components-container-div.md)的flex-warp样式设置为wrap来使用折行能力。
699
700**示例:**
701
702父容器中的图片尺寸固定,当父容器尺寸发生变化,其中的内容做自适应换行。
703
704![zh-cn_image_0000001385645821](figures/zh-cn_image_0000001385645821.gif)
705
706
707```
708@Entry
709@Component
710struct WrapCapabilitySample {
711  @State rate: number = 0.7
712  const imageList: Resource [] = [
713    $r('app.media.flexWrap1'),
714    $r('app.media.flexWrap2'),
715    $r('app.media.flexWrap3'),
716    $r('app.media.flexWrap4'),
717    $r('app.media.flexWrap5'),
718    $r('app.media.flexWrap6')
719  ]
720
721  // 底部滑块,可以通过拖拽滑块改变容器尺寸
722  @Builder slider() {
723    Slider({ value: this.rate * 100, min: 50, max: 70, style: SliderStyle.OutSet })
724      .blockColor(Color.White)
725      .width('60%')
726      .onChange((value: number) => {
727        this.rate = value / 100
728      })
729      .position({ x: '20%', y: '87%' })
730  }
731
732  build() {
733    Flex({ justifyContent: FlexAlign.Center, direction: FlexDirection.Column }) {
734      Column() {
735        // 通过Flex组件warp参数实现自适应折行
736        Flex({
737          direction: FlexDirection.Row,
738          alignItems: ItemAlign.Center,
739          justifyContent: FlexAlign.Center,
740          wrap: FlexWrap.Wrap
741        }) {
742          ForEach(this.imageList, (item) => {
743            Image(item).width(183).height(138).padding(10)
744          })
745        }
746        .backgroundColor('#FFFFFF')
747        .padding(20)
748        .width(this.rate * 100 + '%')
749        .borderRadius(16)
750      }
751      .width('100%')
752
753      this.slider()
754    }.width('100%')
755    .height('100%')
756    .backgroundColor('#F1F3F5')
757  }
758}
759```
760