HarmonyOS 鸿蒙Next应用开发基础架构搭建-多端布局之栅格布局
HarmonyOS 鸿蒙Next应用开发基础架构搭建-多端布局之栅格布局
栅格布局(Grid Layout)在设计和开发领域中扮演着至关重要的角色,尤其是在响应式设计中。它是一种基于固定或可变单元格的布局系统,用于组织和对齐页面上的元素,使其在不同屏幕尺寸下都能保持一致性和美观性。
栅格布局的优势
- 规范性:通过固定的单元格,确保页面元素的一致性和可预测性。
- 响应式设计:栅格布局易于调整,可以适应不同设备和屏幕尺寸,实现响应式设计。
- 易读性和可用性:有序的布局使用户更容易理解和导航网站。
- 效率:对于开发者而言,使用栅格系统可以简化布局过程,减少编码工作量。
栅格布局的组成部分
- 容器(Container):定义了栅格的边界。
- 行(Row):横向分割容器,包含列。
- 列(Column):纵向分割行,用于放置内容。
- 间隔(Gutter):列与列之间的空白空间。
- 单元格(Cell):列的别称,表示栅格中的一个基本单位。
- 断点(Breakpoint):定义布局在不同屏幕尺寸下的变化点。
如上图:红色区域为列,列于列之间为间隔(Gutter)。
在鸿蒙系统中,栅格结合断点,实现栅格布局能力的组件叫栅格组件,需要使用GridRow和GridCol组件。
在实际使用场景中,可以根据需要配置不同断点下栅格组件中元素占据的列数,同时也可以调整Column和Gutter的值,从而实现不同的布局效果。
栅格布局 (GridRow/GridCol)
首先需要了解栅格布局中的断点,栅格系统默认断点将设备宽度分为xs、sm、md、lg四类,尺寸范围如下:
断点名称 | 取值范围(vp) | 设备描述 |
---|---|---|
xs | [0, 320) | 最小宽度类型设备。 |
sm | [320, 520) | 小宽度类型设备。 |
md | [520, 840) | 中等宽度类型设备。 |
lg | [840, +∞) | 大宽度类型设备。 |
在GridRow栅格组件中,开发者根据实际使用场景,通过一个数组,可以自定义最多六个断点。
breakpoints: {value: [‘100vp’, ‘200vp’]}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
表示启用xs、sm、md共3个断点,小于100vp为xs,100vp-200vp为sm,大于200vp为md。
鸿蒙系统中,栅格的默认列数12列,可以根据不同断点设置不同的列数(Column),设置不同的间隔(Gutter),设置栅格子组件占据的栅格容器列数。
- GridRow的columns:设置不同断点的列数
- GridRow的gutter: 设置子元素在水平和垂直方向的间距
- GridCol的offset:设置栅格子组件相对于前一个子组件的偏移列数,默认为0。
- GridCol的span:设置子组件占栅格布局的列数,决定了子组件的宽度,默认为1。、
我们代码演示一下:
@Entry
@Component
struct TestDemo {
build() {
GridRow({
columns: {
sm: 4, // 在小宽度类型设备上,列数为4
md: 8, // 在中等类型设备上,列数为8
lg: 12 // 在大宽度度类型设备上,列数为12
},
gutter: {
x: {
sm: 12, // 在小宽度类型设备上,水平方向间距12
md: 16, // 在中等宽度类型设备上,水平方向间距16
lg: 24 // 在大宽度类型设备上,水平方向间距24
},
y: {
sm: 12, // 在小宽度类型设备上,垂直方向间距12
md: 16, // 在中等宽度类型设备上,垂直方向间距16
lg: 24 // 在大宽度类型设备上,垂直方向间距24
}
}
}) {
<span class="hljs-comment"><span class="hljs-comment">// 重复多个</span></span>
GridCol({
span: {
sm: <span class="hljs-number"><span class="hljs-number">2</span></span>, <span class="hljs-comment"><span class="hljs-comment">// 在小宽度类型设备上,栅格子组件占据的栅格容器2列。</span></span>
md: <span class="hljs-number"><span class="hljs-number">2</span></span>, <span class="hljs-comment"><span class="hljs-comment">// 在中等宽度类型设备上,栅格子组件占据的栅格容器2列。</span></span>
lg: <span class="hljs-number"><span class="hljs-number">2</span></span> <span class="hljs-comment"><span class="hljs-comment">// 在大宽度类型设备上,栅格子组件占据的栅格容器2列。</span></span>
}
}) {
Row(){}
.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.height(<span class="hljs-number"><span class="hljs-number">200</span></span>)
.backgroundColor(Color.Orange)
}
}
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
实现效果如下:
接下来我们进行一下实际业务场景的使用。在日常的业务场景中,经常会有列表信息的呈现,例如下面的商品列表:
在手机等小屏幕设备上为两列布局,如果在大屏上也是两列布局,就浪费了大屏的空间,体验会大打折扣。
为了在大屏和折叠屏上有更好的体验,我们需要根据断点结合栅格组件,实现不同屏幕下的列数和间距控制。
具体代码如下:
class ProductItem {
constructor(imageUrl: Resource, title: string) {
this.imageUrl = imageUrl;
this.title = title;
}
imageUrl: Resource
title: string
}
@Entry
@Component
struct ListDemo {
@State currentBreakpoint: string = ‘unknown’;
@State marginSize: number = 0
@State ListData: Array<ProductItem> = [
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’),
new ProductItem($r(‘app.media.p1’), ‘问界 新M7 Ultra’)
]
build() {
// 配置不同断点下columns和gutter的取值
GridRow({
columns: {
sm: 4,
md: 8,
lg: 12
},
gutter: {
x: {
sm: 12,
md: 16,
lg: 24},
y: {
sm: 12,
md: 16,
lg: 24
}
}
}) {
ForEach(this.ListData, (item: ProductItem)=>{
GridCol({span: {sm: 2, md: 2, lg: 2}}) {
Column(){
Column() {
Image(item.imageUrl).width(‘100%’).height(‘100%’)
}
.aspectRatio(1)
.backgroundColor(’#E5E3E3’)
.borderRadius(6)
.clip(true)
Text(item.title)
.margin({ top: <span class="hljs-number"><span class="hljs-number">4</span></span> })
}.margin({ bottom: <span class="hljs-number"><span class="hljs-number">10</span></span> })
}
})
}
.margin({left: <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.marginSize, right: <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.marginSize})
.onBreakpointChange((currentBreakpoint: string) => {
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentBreakpoint = currentBreakpoint
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (currentBreakpoint === <span class="hljs-string"><span class="hljs-string">'lg'</span></span>) {
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.marginSize = <span class="hljs-number"><span class="hljs-number">24</span></span>
}<span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(currentBreakpoint === <span class="hljs-string"><span class="hljs-string">'md'</span></span>){
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.marginSize = <span class="hljs-number"><span class="hljs-number">16</span></span>
} <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.marginSize = <span class="hljs-number"><span class="hljs-number">12</span></span>
}
})
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
通过对不同断点的列数和间距控制,同时在onBreakpointChange事件中动态修改marginLeft和marginRight的值,达到不同设备不同展示效果。
最新实现效果如下:
手机
折叠屏
平板
除了实现列表在不同设备上的布局,在实际业务中,也会遇到一个页面,需要在不同屏幕上保持尺寸的情况。
例如下面的登录页面:
手机
平板上不做适配
如图这样的页面,如果不做处理的话,在大屏上会进行延伸,导致页面变形。这种情况就需要结合GridRow和GridCol组件以及断点配置进行调整,使其在不同屏幕下都是居中显示,避免拉伸。
实现代码如下:
import router from ‘@ohos.router’;
@Entry
@Component
struct Login {
@State currentBreakpoint: string = ‘unknown’
@State name: string = ‘’
@State password: string = ‘’
build() {
GridRow({
columns: { sm: 4, md: 8, lg: 12 }
}) {
GridCol({
span:{
xs: 4,
sm: 4,
md: 6,
lg: 6,
xl: 6,
xxl: 6
},
offset: {
xs: 0,
sm: 0,
md: 1,
lg: 3,
xl: 3,
xxl: 3,
}
}) {
// 这里是登录的UI
}
}.onBreakpointChange((currentBreakpoint: string) => {
this.currentBreakpoint = currentBreakpoint
})
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
最终实现效果:
手机
折叠屏折叠态
折叠屏展开态
平板
可以看到栅格组件结合断点设置,可以非常方便的优化不同屏幕上的交互体验。
HarmonyOS NEXT应用开发基础架构搭建-设计理念和目录结构
HarmonyOS NEXT应用开发基础架构搭建-路由页面权限控制
HarmonyOS NEXT应用开发基础架构搭建-多端布局之自适应布局
关于HarmonyOS 鸿蒙Next应用开发基础架构搭建-多端布局之栅格布局的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。
嵌套 list 试试