前言
最近在忙个又大又赶的Web项目,根本都抽不出闲暇时刻来写文章,这篇文章开端写第一个字现已是两个礼拜曾经的作业了,中心便是时断时续的,挤点时刻写点挤点时刻再写点,十分困难才把这篇鸿蒙布局的终究一篇文章写完了,这篇文章讲的是鸿蒙布局里边的栅格布局,列表以及媒体查询,三种布局根本都表现出了一个共同点,那便是屏幕适配,一起来看下吧。
栅格布局(GridRow/GridCol)
栅格布局看组件姓名有点跟之前介绍过的Grid
组件很像,全体看上去栅格布局也是将设备屏幕分红一小格一小格的展现子企图,区别在于,Grid
当你设置好了穿插轴方向上的子视图个数的时分,无论屏幕巨细怎样变,穿插轴方向上的视图数量是不会变的,变的是子视图的巨细,可是在一些宽屏设备上,子企图假如变得太大,也影响视觉上的体验,所以栅格布局在这一点上做了区别,它会在设备的水平宽度上设置一套断点规则,每一种断点就适当于是一种屏幕巨细区间,在每个区间里边,终究页面呈现的布局是不相同的,那么什么是断点呢?不是平常咱们说的断点调试那种断点,这个断点适当于给一种屏幕起了一个姓名,总共有下面几个姓名
- xs:最小宽度类型设备
- sm:小宽度类型设备
- md:中等宽度类型设备
- lg:大宽度类型设备
- xl:特大宽度类型设备
- xxl:超大宽度类型设备
写过Web的必定对这些姓名都不陌生,在Web里边Col组件也能够经过设置断点来适配屏幕,而且用法同栅格布局根本一致,在栅格布局中,经过设置breakpoints
来设置断点,用法如下
breakpoints
里边有个value
,咱们给value
设置了一个数组,这个数组啥意思呢,它代表着一个个区间,当设备宽度小于200vp的时分,当时断点便是xs,当设备宽度大于200vp小于500vp的时分,设备断点是sm,以此类推下去,所以由于咱们总共就六个断点,所以value
这个数组的长度最大不能超过5,那么这个时分或许有的人就有疑问了,干啥要设置这些区间呢,愣费事的…还记得刚才咱们提到的栅格布局会依据不同的屏幕巨细区间来呈现不同的布局吗?关键时刻到了,栅格布局GridRow
默许将屏幕宽度分红12列,而它的子视图规定运用GridCol
组件,GridCol
会依据设置好的断点,来给每个断点设置每一个GridCol
占的列数,比方这儿给五个断点别离设置不同列数
小屏幕xs上单个视图占了2格,再大点的屏幕sm上占了3格,然后后面顺次设置相应的列数,这儿还创立了12个色块,下面来看下在不同尺度的屏幕上的布局摆放情况
能够看到在正常手机上竖屏的时分,咱们断点是来到了sm,所以在水平方向上展现四个,当手机屏幕变为横屏时分,断点就变成了md,水平方向上展现的个数也发生了改动,而变成平板横屏的时分,区间断点就来到了lg,这儿是依照默许列数为12在计算每一项占的列数,咱们还能够自定义栅格布局的列数,经过设置column
参数
在上面的代码中仅仅只增加了column:24
的设置,将GridRow
占的列数增加到了24列,这个时分咱们的布局又发生了改动
由于咱们现已知道手机设备上竖屏时分断点是在sm上,sm咱们是设置了3列,一切当GridRow
的默许列数变成24的时分,咱们能够从作用图上看到手机设备竖屏时分水平方向上的子项数量变成了八个,同理在旋转设备以及切换至平板时分,水平方向上的子项数量都增加了
span
到现在为止咱们GridCol
的span
特点都是设置的GridColColumnOption
,span
代表着一个子项所占的列数,默许占1列,咱们还能够给span独自设置个number
,那么这个就表示在任何断点区间内,子项占的列数都是固定的,比方咱们将上面的比方更改下,让每个子项占2列,代码如下
这儿仍旧把GridRow
的默许列数变回12,每个GridCol
占2列,那么水平方向一行应该永远最多只要六个,看下作用
gutter
当咱们想要给GridRow
里边的子项设置距离的时分,能够运用GridRowOptions
供给的gutter
特点
发现gutter
既能够设置一个Length
,也能够设置一个GutterOption
,当设置一个Length
的时分,能够给gutter
设置一个number
类型的值,也能够是一个string
,也能够是Resource
这些都表示子项水平方向笔直方向的距离是相同的,比方给上面比方中的GridRow
增加10vp
的距离,代码能够这样写
终究作用就如上图所示,水平笔直方向的距离都是相同的,那假如水平跟笔直方向的距离不相同,咱们就得设置GutterOption
,别离定义x
与y
方向上的距离
x
,y
的取值也有两种,Length
就不必多说了,GridRowSizeOption
是什么东西呢?点进去一看,发现GridRowSizeOption
也是能够依据断点区间来设置巨细的
下面来写点比方,来给上面的栅格布局的水平与笔直方向设置不同的距离值,先设置Lendth
类型
作用图上能够看到笔直方向的距离现已比水平方向的要大了,咱们再用GridRowSizeOption
来试一下
作用图上能够看出,在不断改动屏幕宽度下,GridRow
的子项之间的距离也都发生了改动
offset
GridCol
还能够设置相对于前一项的偏移量,这个偏移量也适当于偏移的列数,比方咱们给每个子项偏移2列,代码能够这样写
偏移了两列今后,作用图如下
由于每个GridCol
默许占1列,然后偏移了两列,也便是说每一项需求3列的空间,然后咱们GridRow
默许列数为12列,所以终究展现出来的作用才是屏幕宽度上一行有四个子项
order
order
能够设置子组件在GridRow
里边的摆放次序,当不设置order
或许设置相同的order
的时分,子组件摆放的次序依照代码次序进行,当子组件设置了不同的order
的时分,order
越小的子组件摆放越靠前,不设置order
的子组件要比设置order
的子组件摆放靠前,下面来看个比方
这儿有个长度为12的数组orderValues
,数组里边的值从0顺次到11,然后在GridRow
里边遍历数组并创立个Text
去展现值,这儿GridCol
没有设置order
特点,终究Text
的摆放次序应该是同orderValues
次序相同的,咱们看下
然后咱们给GridCol
增加上order
特点,每一个GridCol
的order
值便是数组长度减去子项的下标,代码如下
从作用图上能够看出,设置了order
值今后,第一个被创立的Text
被摆放到了布局的终究一个,终究一个Text
摆放到了第一个,咱们再加点逻辑,比方奇数项不设置order
,偶数项的order
的计算方法不变
跟之前说的相同,不设置order
的子项仍是依照代码次序摆放而且排在设置过order
的偶数项前面
列表(List)
列表组件List
是比较常用的组件之一,在需求展现比较大的数量的时分,列表组件往往都是首选,ArkUI中的列表组件也跟其他前端框架相同拥有一些相同的特性,下面来逐一了解下
约束与布局
列表组件中的子组件只能是ListItem
与ListItemGroup
,前者是展现单个子项布局,后者则是一个ListItem
的调集,能够将多个子项兼并在一起展现,最常见的便是手机里边的通讯录,下面是一个简略的列表展现数据的代码
这儿有个长度为10的number
类型的数组,经过在List
里边运用ForEach
遍历数组逐一生成ListItem
,由于每个子项的高度设置成60vp
,而List
没有设置高度,所以终究List
将一切数据都展现了出来,而且它的高度便是一切子项的高度和,也便是600vp
,假如想要让列表里边的子项能够翻滚起来,一个方法便是扩展数组的数据量,或许加大子项的高度,让一切子项高度的和大于屏幕,这样List
就能够翻滚起来,另一个方法便是给List
设置一个高度值,这样里边的子项高度和假如大于这个高度值的话,List
里边的子项也能够翻滚,比方给上面的列表增加个300vp
的高度值后,作用如下
整个列表的高度现已被约束在了300vp
内,里边的子项要经过翻滚才干检查一切数据,这个便是List
设置与不设置高度的区别,其实这儿有个用词不当的当地,这儿的高度其实应该换成主轴方向的巨细,由于List默许主轴方向是笔直方向,所以列表组件默许的主轴方向巨细便是它的高度巨细,假如咱们想要改动列表的主轴方向,能够经过设置listDirection
来切换
假如不设置listDirection
,列表的默许主轴特点便是Axis.Vertical
,而除了在主轴方向布局之外,List
组件还支撑在穿插轴方向布局,也便是穿插轴方向上的子项数量能够大于一个,经过lanes
函数来设置,lanes
函数接纳的参数类型有两种,一种是直接传一个number
,比方上面的列表我想让它穿插轴方向上展现三个子项,能够这样设置
一会儿List
就变成了Grid
,其实lanes
这个函数拿来适配各种屏幕比较合适,比方说当子项的布局不是很杂乱的时分,在宽屏设备上就能够经过设置lanes
来让List
在穿插轴方向上多显现几个子项,漂亮还节省空间,lanes
函数还能够接纳LengthConstrain
类型的参数,会设置一个最小穿插轴长度与最大穿插轴长度,用这两个值与List
的尺度一起决定穿插轴上应该展现的列数,比方上面这个比方咱们改一下
设置了最小穿插轴长度为100vp
,最大穿插轴长度为200vp
,然后由于List
没有设置listDirection
,所以List
的穿插轴方向为水平方向,width
为150vp
作为穿插轴方向上的巨细,那么终究List
会展现几列呢?咱们看下
终究会展现一列,由于List
的最小穿插轴长度为100vp
,List
穿插轴方向上巨细为150vp
,小于最小穿插轴长度的两倍,所以只能展现一列,假如咱们把List
穿插轴上的巨细改成200vp
或许比200vp
大,那么列数就会改动了,咱们试一下
能够看到现在列数现已变成两列了,所以LengthConstrain
也能够作为适配各种屏幕的一种方法
列表款式
常常在运用列表的时分,避免不了要调整一些列表款式,下面来介绍下ArkUI中List
组件是怎样设置与调整这些款式的
设置距离
在List
组件中运用space
特点给列表的子项之间增加距离,下面来举个比方,给列表的子项之间增加15vp的距离
能够看到子项之间立马就呈现了15vp巨细的距离,非常简略
设置分割线
除了距离之外,分割线也是常常会去设置的,列表组件里供给了divider
来设置分割线,其中strokeWidth
与color
别离设置分割线的粗细以及色彩,startMargin
与endMargin
别离设置分割线的左右边距,来看下具体运用
这儿给列表设置了分割线,其中分割线的粗细是5vp,色值为赤色,左边距为20vp,右边距为10vp,作用如下
分组列表
在前面有说过,列表组件里边的子项只能是ListItem
与ListItemGroup
,而后者便是用来给列表设置分组的,常见的便是咱们手机通讯录列表,下面来简略做一个带分组的列表,首先准备好需求展现的数据
然后经过一次ForEach
遍历,创立对应的ListItemGroup
,而且给ListItemGroup
设置header
特点
注意的是这儿的header
接纳的是一个CustomBuilder
类型的参数,也便是不能直接给它这是个字符串,需求传入一个自定义组件,所以咱们在build
函数外面新建一个@Builder
的自定义组件head
,这个组件就用来创立一个简略的展现title
的布局
创立好header
之后,在ListItemGroup
内部在做一次ForEach
遍历,将每一个members
里边的字符串都显现在对应的分组里边,这儿也给每一个分组子项也新建了一个@Builder
的自定义组件child
这样一个分组列表就做好了,作用如下
可是大多数情况下,这样的分组列表都要支撑一个功用,那便是header吸顶,而这样的功用在咱们这个列表组件中完成起来很容易,运用sticky
函数就能够完成了,内部接纳参数StickyStyle.Header
响应翻滚方位
在列表的一些业务场景中,有些场景就需求要求能够监听列表的翻滚工作来做出相应的操作,最简略的比方,当一个列表开端翻滚的时分,底部会呈现一个按钮,点击后会让列表从头回到顶部,那么首先第一步就需求监听列表的翻滚工作,在List
组件中供给了onScrollIndex
函数来监听列表的滑动工作,然后会回来当时列表处于最顶部的子项的下标值,具体用法如下
这是一个简略展现十五条数据的列表,当列表翻滚的时分,在onScrollIndex
中就会回来最顶部的子项下标值,那么咱们就来做个功用,当列表第三项呈现在列表的最顶部的时分,屏幕右下方会呈现一个按钮,显现“回到顶部”,已然要在屏幕右下方放个按钮,咱们就要让List
组件外面在套个Stack
组件,让List
与回到顶部的按钮在Stack
里边是同级关系
接着创立一个@State
的状况变量,并在onScrollIndex
中跟着列表翻滚去更新这个状况变量,而且判别,只要当这个变量大于2的时分,回到顶部的按钮才呈现,不然就隐藏
按钮的隐藏呈现逻辑完成后,咱们就要考虑怎样点击按钮后让列表回到顶部,这种控制列表翻滚方位的作业,咱们交给Scroller
去做,所以咱们再创立一个Scroller
并将它作为参数传给List
组件
再给按钮增加点击工作,在工作中只需求调用Scroller
的scrolToIndex
函数就好了
媒体查询(mediaquery)
在日常做一些ui方面的适配作业上,总是会依据设备的不同状况展现不相同的ui款式,这些状况比方像是设备分辨率,设备的宽高,以及反正屏切换之类,特别像是反正屏切换,展现的布局完全便是两个样子,所以怎样正确的去判别设备处于什么状况才干帮助咱们有用的去完成适配作业,在鸿蒙当中,会运用媒体查询去做这些作业,简略的说,媒体查询便是经过一些条件句子来让屏幕去判别当时是否契合该条件,是就履行一段逻辑,不是就履行别的一条逻辑,这个条件大致的结构如下
这儿的media-type现在只要一个screen
值,所以可写可不写,media-logic-operation是媒体逻辑操作符,运用这些操作符能够将不同的媒体特征组合起来构成愈加杂乱的条件句子,媒体逻辑操作符有如下几种
- and:能够将不同的媒体特征以“与”的逻辑连在一起,只要当一切媒体特征都会true,整个媒体查询条件才建立
- or:将不同的媒体特征以“or”的逻辑连在一起,只要存在一条特征为true,整个查询条件就建立
- not:取反媒体查询成果,媒体查询成果不建立时回来true,不然回来false
- only:当整个表达式都匹配时,才会使用选择的款式,能够使用在避免某些较早的版本的浏览器上产生歧义的场景
- **comma(, **):与上面的or相同
media-feature是媒体特征,像分辨率,屏幕的宽高,反正屏都属于媒体特征,以下是一切媒体特征以及其解说
- height:使用页面可制作区域的高度
- min-height:使用页面可制作区域的最小高度
- max-height:使用页面可制作区域的最大高度
- width:使用页面可制作区域的宽度
- min-width:使用页面可制作区域的最小宽度
- max-width:使用页面可制作区域的最大宽度
- resolution:设备的分辨率
- min-resolution:设备的最小分辨率
- max-resolution:设备的最大分辨率
- orientation:屏幕的方向
- device-height:设备的高度
- min-device-height:设备的最小高度
- max-device-height:设备的最大高度
- device-width:设备的宽度
- device-type:设备的类型
- min-device-width:设备的最小宽度
- max-device-width:设备的最大宽度
- round-screen:屏幕类型,圆形屏幕为true,非圆形屏幕为false
- dark-mode:体系为深色形式时为true,不然为false
介绍完这些概念之后,咱们就开端着手试试看这个媒体查询究竟怎样运用的,首先是导入这个媒体查询模块,直接import进来
然后调用matchMediaSync
函数去设置媒体查询条件,现在手里只要模拟器,找来找去只能测验个反正屏切换功用,比方条件为当屏幕为横屏的时分,条件句子便是下面这样
注意在条件句子里边,每一个媒体特征都必须用括号括起来,多个媒体特征在一起用媒体逻辑操作符连起来,这儿只判别是否为横屏,所以只要一个媒体特征,再将这个条件句子塞入到matchMediaSync
函数里去,完整的代码如下
listener
便是一个监听器,监听这个查询条件建立的机遇,然后还要让listener
绑定一个回调函数observeLandscape
,这个回调用来处理应媒体条件建立时分做什么作业,不建立时分做什么作业
绑定的机遇就放在aboutToAppear
函数中
首要的代码都写好了,现在能够写个功用验证下,比方界面上有个色块,还有段文字,当屏幕为横屏状况时分,色块显现绿色,文字显现“现在是横屏”,反之色块就显现赤色,文字显现“现在是竖屏”,所以咱们先创立两个状况变量来记录色彩与案牍这两个值
然后在回调函数observeLandscape
里写上各个状况的逻辑
终究再简略创立两个组件别离展现色彩与案牍
一切代码都写完了,终究看下作用
总结
至此,一切的鸿蒙布局都挨个介绍了一遍,都是些根本用法,当然也遇到些比较难理解的概念,这些仍是得需求咱们经过多实践多揣摩才干把这些东西都理解透,别的在学习过程中,咱们仍是能够从鸿蒙这些布局的用法上能看到一些Flutter,Compose和Web的一些影子,尤其是这篇文章里介绍的栅格布局,断点概念完全跟Web一摸相同,所以对于有过声明式UI开发经历的人来说,学鸿蒙的确是会轻松不少