语雀知识库地址:语雀HarmonyOS知识库
飞书知识库地址:飞书HarmonyOS知识库
本文示例代码地址:Gitee 仓库地址
嗨,大家好,我是小白
上篇文章向大家介绍了 ArkTS 中我们经常使用到的几种基础组件,Text、Button 等。但是这些基础组件并不能完全满足一个 APP 的布局管理
就好比我们在使用 APP 时,常常看到的商品列表、登陆界面、悬浮按钮等等,都是通过一系列的布局方式来呈现的
比如我们在使用购物软件查询商品时,展示出来的是一个列表布局;等应用的登录界面,用户名与输入框、用户名行与密码行属于一个不同方向的线性布局;又比如表格中的每一列宽度均匀分布,这又属于弹性布局
举一个栗子,假设我们要一个登录界面,该界面有用户名、密码及输入框,当我们不加任何容器的情况下,呈现出来的是下面这种效果
这样子我们的页面虽然有了元素,但是在整体布局上不是很合理,按理来说输入框应该是与文本同行展示,而现在缺是换行展示
这是因为当前没有给向同行的组件添加布局方式而导致的这种效果
这篇文章就来探讨一下常用的布局方式
线性布局是应用中最常用的布局,通过线性容器 Row
和 Column
构建
线性布局是其他布局的基础,其子元素在水平方向和垂直方向依次排列
线性布局的排列方向由所选容器组件决定,Column 容器内子元素按照垂直方向排列,Row 容器内子元素按照水平方向排列。根据不同的排列方向,可选择使用 Row 或 Column 容器创建线性布局
Column(value?: {space?: string | number})
Row(value?:{space?: number | string })
Column({ space: 10 })
Row({ space: 10 })
Column({ space: 10 })
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
Row({ space: 10 })
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
交叉轴为垂直方向时,取值为VerticalAlign类型,水平方向取值为HorizontalAlign
alignSelf 属性用于控制单个子元素在容器交叉轴上的对齐方式,其优先级高于 alignItems 属性,如果设置了 alignSelf 属性,则在单个子元素上会覆盖 alignItems 属性
在线性布局下,常用空白填充组件Blank,在容器主轴方向自动填充空白空间,达到自适应拉伸效果
Row和Column作为容器,只需要添加宽高为百分比,当屏幕宽高发生变化时,会产生自适应效果
自适应缩放是指子组件随容器尺寸的变化而按照预设的比例自动调整尺寸,适应各种不同大小的设备。在线性布局中,可以使用以下两种方法实现自适应缩放。
自适应延伸是指在不同尺寸设备下,当页面的内容超出屏幕大小而无法完全显示时,可以通过滚动条进行拖动展示。这种方法适用于线性布局中内容无法一屏展示的场景。通常有以下两种实现方式
列表是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、音乐列表、购物清单等)
使用列表可以轻松高效地显示结构化、可滚动的信息。通过在 List 组件中按垂直或者水平方向线性排列子组件 ListItemGroup 或 ListItem ,为列表中的行或列提供单个视图,或使用 ForEach 迭代一组行或列,或混合任意数量的单个视图和 ForEach 结构,构建一个列表。List 组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件
List(value?: {space?: number | string, initialIndex?: number, scroller?: Scroller})
List({ space: 20, initialIndex: 0 })
List({ space: 20, initialIndex: 0 }) {
ForEach(this.arr, (item) => {
ListItem() {
Text('' + item)
.width('100%')
.height(100)
.fontSize(16)
.textAlign(TextAlign.Center)
.borderRadius(10)
.backgroundColor(0xFFFFFF)
}
}, item => item)
}
.listDirection(Axis.Vertical) // 排列方向
.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果
.onScrollIndex((firstIndex: number, lastIndex: number) => {
console.info('first' + firstIndex)
console.info('last' + lastIndex)
})
.width('90%')
.height('100%')
}
List 组件的相关事件参考官方文档
弹性布局提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间
容器默认存在主轴与交叉轴,子元素默认沿主轴排列,子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸
弹性布局在开发场景中用例特别多,比如页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等等
Flex(value?: { direction?: FlexDirection, wrap?: FlexWrap, justifyContent?: FlexAlign, alignItems?: ItemAlign, alignContent?: FlexAlign })
Flex({
direction: FlexDirection.Row,
wrap: FlexWrap.NoWrap,
justifyContent: FlexAlign.Center,
alignItems: ItemAlign.Center,
alignContent: FlexAlign.Center
})
通过Flex组件的alignItems参数设置子组件在交叉轴的对齐方式
子组件的 alignSelf 属性也可以设置子组件在父容器交叉轴的对齐格式,且会覆盖 Flex 布局容器中 alignItems 配置
在弹性布局父组件尺寸不够大的时候,通过子组件的下面几个属性设置其在父容器的占比,达到自适应布局能力
层叠布局用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局。层叠布局通过Stack容器组件实现位置的固定定位与层叠,容器中的子组件依次入栈,后一个子元素覆盖前一个子元素,子元素可以叠加,也可以设置位置
层叠布局具有较强的页面层叠、位置定位能力,其使用场景有广告、卡片层叠效果等
Stack(value?: { alignContent?: Alignment })
Stack({ alignContent: Alignment.Center })
Stack({ alignContent: Alignment.Center })
.alignContent(Alignment.Center)
Stack容器中兄弟组件显示层级关系可以通过 Z序控制的 zIndex 属性改变。zIndex 值越大,显示层级越高,即 zIndex 值大的组件会覆盖在 zIndex 值小的组件上方
Stack({ alignContent: Alignment.BottomStart }) {
Column() {
Text('Stack子元素1').fontSize(15)
}.width(50).height(50).backgroundColor(0xffd306).zIndex(2)
Column() {
Text('Stack子元素2').fontSize(12)
}.width(75).height(75).backgroundColor(Color.Pink).zIndex(1)
Column() {
Text('Stack子元素3').fontSize(15)
}.width(100).height(100).backgroundColor(Color.Grey)
}.margin({ top: 10 }).width(125).height(125).backgroundColor(0xe0e0e0)