题外话:栅格布局最初是在web 端应用的,为了解决一个系统在不同的屏幕,和不同的设备上可以不进行多次开发的问题,希望一次开发可以最大化的适配用户的不同类型设备,解决方案:将屏幕采用断点的方式进行布局分割,然后通过响应式布局方式实现不同的屏幕上展示不同布局的方式。
而HarmonyOS 目前作为移动端的操作系统之一,各大厂家的设备屏幕大小不一样,如何让一套代码适配多个屏幕呢?从API9 开始引入了这样的设计,设计了GridRow 容器和子组件GridCol
这个容器harmonyOS 工程师 写的自定义组件,但是使用方的开发者,为了让开发者更方便的使用以上场景所说的问题,设计思路如下:
1 有一定的规律性,将布局划分为等宽列数和行数,这样就可以方便的对页面布局元素进行定位和排版。
2 统一的定位标注(什么是定位标注)
3 不同设备上元素在不同设备展示的时候如果只元素发生变化,间距不发生变化,那么界面会非常的丑,为了解决这个问题引入了距离调整方法,
4 不同的屏幕大小下每行每列展示的元素数量不一样,如果超过一行或者一列如何解决,希望实现自动换行。
解决方案:首先将移动设备的屏幕按照宽度作为断点的依据,分为了xs、sm、md、lg四类,尺寸范围如下::
在GridRow栅格组件中,允许开发者使用breakpoints自定义修改断点的取值范围,最多支持6个断点,除了默认的四个断点外,还可以启用xl,xxl两个断点,支持六种不同尺寸(xs, sm, md, lg, xl, xxl)设备的布局设置。
设置方式: breakpoints: {value: [‘320vp’, ‘520vp’, ‘840vp’, ‘1080vp’]}
表示启用xs、sm、md、lg、xl共5个断点,小于320vp为xs,320vp-520vp为sm,520vp-840vp为md,840vp-1080vp为lg,大于1080vp为xl。
UI的布局宽度有两种表达方式 1 在不是满屏的情况下用容器宽度 ComponentSize 2 在满屏的情况下用窗口宽度WindowSize
用reference 属性进行设置:
GridRow({breakpoints: {value: ['200vp', '300vp', '400vp', '500vp', '600vp'],reference: BreakpointsReference.WindowSize}
})
**栅格容器默认将屏幕的宽度划分为12列,可以通过对子组件的span 设置不同的断点下子元素占用的屏幕宽度。**
GridRow({breakpoints: {value: ['200vp', '300vp', '400vp', '500vp', '600vp'],reference: BreakpointsReference.WindowSize}
}){GridCol({span: {xs: 2, // 在最小宽度类型设备上,栅格子组件占据的栅格容器2列。sm: 3, // 在小宽度类型设备上,栅格子组件占据的栅格容器3列。md: 4, // 在中等宽度类型设备上,栅格子组件占据的栅格容器4列。lg: 6, // 在大宽度类型设备上,栅格子组件占据的栅格容器6列。xl: 8, // 在特大宽度类型设备上,栅格子组件占据的栅格容器8列。xxl: 12 // 在超大宽度类型设备上,栅格子组件占据的栅格容器12列。}}){具体的子组件内的布局}.backgroundColor(color)}**同时可以将父容器GridRow栅格容器的列数通过columens 的属性修改,比如修改为6,意味着在不同的断点下,子组件最大的列为6列*
GridRow({ columns: 6 }) {}
也可以在不同的断点下对栅格容器的列进行定义:GridRow({ columns: { sm: 4, md: 8 }, breakpoints: { value: ['200vp', '300vp', '400vp', '500vp', '600vp'] } }) {}
*代表:小于等于sm 大小的屏幕最大列数都是4,而大于等于md 屏幕大小的列数都是8.
那么下面是什么意思呢?
GridRow({ columns: { sm: 4, md: 8,lg: 12}, breakpoints: { value: ['200vp', '300vp', '400vp', '500vp', '600vp'] } }) {}
GridRow 默认的布局方向是水平方向,并且是从左到右,有些布局是从右到左如何设置。可以通过direction
GridRow({ direction: GridRowDirection.RowReverse }){}
GridRow通过gutter属性设置子元素在水平和垂直方向的间距。
不能在不同的断点下设置间距
如果只写数字,那么代表水平和垂直方向都是固定的间距如设置水平和垂直方向的间距都为20
GridRow({ gutter: 20}){}
也可以水平和垂直方向单独设置如:
GridRow({ gutter: {x:20,y:30}}){}
对于子组件GridCol 的设置重点三个属性
1 span 代表 子组件在父容器中占用的列数。
可以设置在所有的断点下都占用2列数如:
Row() {GridRow({ columns: 8}){GridCol({span:2 })}
也可以在不同的断点下设置不同的列数
GridRow({ columns: 8 }) {GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }) { }}
2 offset 偏移量,代表子组件在屏幕宽度分割列后,每个子组件和前面的子组件间隔几个组件,默认是0
比如:屏幕默认12列,设置每个子组件之间间隔2列
GridRow() {
GridCol({ offset: 2 }) { }}
可也是在不同的断点下设置偏移量如:将屏幕分割成8列,
GridRow({ columns: 8 }) {
GridCol({ offset: { xs: 1, sm: 2, md: 3, lg: 4 } }) { }
}
3 order 用来设置子组件的顺序,顺序按照设置值从小到大排序,如果没有设置值按照组件顺序排序,默认值为0
通过这些属性可以实现金刚区在不同的屏幕下不同的展示效果:
如金刚区的入口总计12个,在xms 下每行展示3个,在lg 的屏幕下每行展示12个
GridRow({ }) {
GridCol({ span: { xs: 4, lg: 1 } }) { ForEco(){
金刚区布局} }
}