鸿蒙PC开发——重复布局
重复布局是指在空间充足时,重复使用相同或相似的结构、组件或排列方式,用以展示更多内容、保持视觉一致性并提高用户体验。常用的重复布局包括列表布局、瀑布流布局、轮播布局和网格布局。
【高心星出品】
鸿蒙PC开发——重复布局
重复布局是指在空间充足时,重复使用相同或相似的结构、组件或排列方式,用以展示更多内容、保持视觉一致性并提高用户体验。常用的重复布局包括列表布局、瀑布流布局、轮播布局和网格布局。
| 响应式布局方式 | 典型布局场景 |
|---|---|
| 列表布局 | List组件+断点 |
| 瀑布流布局 | WaterFlow组件+断点 |
| 轮播布局 | Swiper组件+断点 |
| 网格布局 | Grid组件+断点 |
媒体查询工具类
export class WidthBreakpointType<T> {
sm: T;
md: T;
lg: T;
// 构造函数
constructor(sm: T, md: T, lg: T) {
this.sm = sm;
this.md = md;
this.lg = lg;
}
// 根据断点返回值
getValue(widthBp: WidthBreakpoint): T {
if (widthBp === WidthBreakpoint.WIDTH_XS || widthBp === WidthBreakpoint.WIDTH_SM) {
return this.sm;
}
if (widthBp === WidthBreakpoint.WIDTH_MD) {
return this.md;
} else {
return this.lg;
}
}
}
列表布局
列表布局基于横向断点,动态调整列数以实现重复布局。
布局效果

实现方案
设置不同横向断点下,List组件的lanes、space属性实现目标效果。
参考代码
List({
space: new WidthBreakpointType(8, 12, 16, 16).getValue(this.mainWindowInfo.widthBp),
scroller: this.listScroller
}) {
// ...
}
.scrollBar(BarState.Off)
.lanes(new WidthBreakpointType(1, 2, 3, 3).getValue(this.mainWindowInfo.widthBp), 12)
代码逻辑走读:
- 创建列表组件:使用
List构造函数初始化一个列表组件,设置space属性为根据当前窗口宽度动态计算的值,确保列表项之间有适当的间距。同时,指定scroller属性为this.listScroller,用于控制列表的滚动行为。 - 配置滚动条:通过调用
.scrollBar(BarState.Off)方法,将列表的滚动条状态设置为关闭,这意味着用户在浏览列表时不会看到滚动条。 - 设置列表行数和宽度:使用
.lanes()方法,根据当前窗口宽度动态设置列表的行数和宽度。getValue(this.mainWindowInfo.widthBp)方法用于获取当前窗口宽度对应的值,确保列表布局在不同设备上都能良好显示。
瀑布流布局
瀑布流布局基于横向断点,动态控制列数以实现重复布局。
布局效果
实现方案
设置不同横向断点下,WaterFlow组件的columnsTemplate属性实现目标效果。
示例代码
WaterFlow() {
LazyForEach(this.dataSource, (item: number, index: number) => {
FlowItem() {
Row() {}
.width('100%')
.height('100%')
.borderRadius(16)
.backgroundColor('#F1F3F5')
}
.width('100%')
.height(this.itemHeightArray[index])
}, (item: number, index: number) => JSON.stringify(item) + index)
}
.columnsTemplate(`repeat(${new WidthBreakpointType(2, 3, 4, 4).getValue(this.mainWindowInfo.widthBp)}, 1fr)`)
.columnsGap(12)
.rowsGap(12)
.width('100%')
代码逻辑走读:
-
组件定义:定义了一个名为
WaterFlow的组件。 -
数据遍历:使用
LazyForEach遍历dataSource数据源,为每个数据项创建一个FlowItem组件。 -
FlowItem组件创建
:
- 每个
FlowItem包含一个Row布局。 Row布局的样式属性设置为宽度100%,高度根据数据项的索引动态调整,圆角为16,背景色为#F1F3F5。
- 每个
-
响应式布局:通过
columnsTemplate属性,根据屏幕宽度变化动态调整列数,使用columnsGap和rowsGap属性设置列间距和行间距。 -
宽度设置:整个
WaterFlow组件的宽度设置为100%。
轮播布局
轮播布局基于横向断点,动态控制视窗内显示元素的个数以实现重复布局。
布局效果

实现方案
设置不同横向断点下,Swiper组件的displayCount、prevMargin、nextMargin和indicator属性实现目标效果。
示例代码
Swiper() {
// ...
}
.displayCount(new WidthBreakpointType(1, 2, 3, 3).getValue(this.mainWindowInfo.widthBp))
// Setting the navigation point Style of the swiper.
.indicator(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? Indicator.dot()
.itemWidth(6)
.itemHeight(6)
.selectedItemWidth(12)
.selectedItemHeight(6)
.color('#4DFFFFFF')
.selectedColor(Color.White) : false
)
// The sizes of the front and rear banners on the MD and LG devices are different.
.prevMargin(new WidthBreakpointType(0, 12, 64, 64).getValue(this.mainWindowInfo.widthBp))
.nextMargin(new WidthBreakpointType(0, 12, 64, 64).getValue(this.mainWindowInfo.widthBp))
代码逻辑走读:
-
Swiper组件定义:
- 使用
Swiper()定义了一个轮播图组件。
- 使用
-
设置显示数量:
.displayCount(new WidthBreakpointType(1, 2, 3, 3).getValue(this.mainWindowInfo.widthBp)):根据当前窗口的宽度断点(widthBp)设置显示的轮播图数量。
-
设置导航点样式:
-
.indicator(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? Indicator.dot()...- 判断当前窗口宽度是否为
WIDTH_SM(小屏幕),如果是,则设置导航点样式为圆点(Indicator.dot())。 - 设置导航点的宽度、高度、颜色等样式属性。
- 判断当前窗口宽度是否为
-
如果不是小屏幕,则不显示导航点(
false)。
-
-
设置前后轮播图的边距:
-
.prevMargin(new WidthBreakpointType(0, 12, 64, 64).getValue(this.mainWindowInfo.widthBp))- 根据当前窗口的宽度断点设置前一个轮播图的边距。
-
.nextMargin(new WidthBreakpointType(0, 12, 64, 64).getValue(this.mainWindowInfo.widthBp))- 根据当前窗口的宽度断点设置后一个轮播图的边距。
-
网格布局
网格布局基于横向断点,动态控制列数/行数以实现重复布局。
布局效果

网格布局将容器按行和列划分为规则的网格,每个子组件严格对齐,实现均分和占比能力,详情请参考创建网格;瀑布流布局子组件高度支持自定义,无需对齐,适合展示高度不一的内容,详情请参考创建瀑布流。
实现方案
设置不同横向断点下,Grid组件的columnsTemplate属性实现目标效果。在不设置Grid组件行数的情况下,行数 = 展示元素数量 / 列数。Grid组件其他布局模式,请参考rowsTemplate。
示例代码
Grid() {
ForEach(this.infoArray.slice(new WidthBreakpointType(4, 2, 0, 0).getValue(this.mainWindowInfo.widthBp)),
(item: number) => {
// ...
}, (item: number, index: number) => JSON.stringify(item) + index)
}
.width('100%')
.columnsTemplate(`repeat(${new WidthBreakpointType(2, 3, 4, 4).getValue(this.mainWindowInfo.widthBp)}, 1fr)`)
.columnsGap(12)
.rowsGap(12)
代码逻辑走读:
- 网格定义:使用
Grid()定义了一个网格布局容器。 - 动态迭代:通过
ForEach方法遍历infoArray数组,数组长度由WidthBreakpointType对象的getValue方法根据mainWindowInfo.widthBp计算得出。 - 元素处理:对于数组中的每个元素(
item),执行一个匿名函数进行处理(具体处理逻辑未提供)。 - 唯一键生成:使用
JSON.stringify(item) + index作为每个元素的唯一键。 - 网格样式设置
- 设置网格宽度为
100%。 - 使用
columnsTemplate方法定义列模板,列数由WidthBreakpointType对象的getValue方法计算得出。 - 设置列间距为
12,行间距为12。
- 设置网格宽度为
更多推荐



所有评论(0)