项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star
效果演示
1. 引言
在上一部分中,我们介绍了Column组件的垂直对齐能力和弹性空间分配的基本概念,并分析了三段式布局的整体结构。本教程将继续深入探讨中间内容区的弹性空间分配实现和底部按钮栏的详细设计,帮助开发者掌握更复杂布局的构建技巧。
2. 中间内容区:弹性空间分配实现
2.1 Flex容器的使用
在我们的案例中,中间内容区使用了Flex容器来实现弹性空间分配:
// 弹性填充区域(中间内容) Flex() { Text('中间内容\n弹性填充') .textAlign(TextAlign.Center) .flexGrow(2) // 父容器分配给该Text的宽度为剩余宽度的2/3 Text(' 弹性填充') .textAlign(TextAlign.Center) .flexGrow(1) // 父容器分配给该Text的宽度为剩余宽度的1/3 } .width('100%') .backgroundColor(0xF0F0F0)
2.2 Flex与Column的区别
特性 |
Flex |
Column |
默认方向 |
水平方向 |
垂直方向 |
主轴 |
默认为水平方向 |
垂直方向 |
交叉轴 |
默认为垂直方向 |
水平方向 |
适用场景 |
需要在一行内灵活分配空间 |
需要垂直排列组件 |
在这个案例中,我们使用Flex容器是为了在水平方向上分配空间,这是Flex的默认行为。如果需要在垂直方向分配空间,可以通过设置Flex的direction属性为FlexDirection.Column来实现。
2.3 Text组件的flexGrow属性详解
在Flex容器中,我们为两个Text组件分别设置了不同的flexGrow值:
Text('中间内容\n弹性填充') .textAlign(TextAlign.Center) .flexGrow(2) // 父容器分配给该Text的宽度为剩余宽度的2/3 Text(' 弹性填充') .textAlign(TextAlign.Center) .flexGrow(1) // 父容器分配给该Text的宽度为剩余宽度的1/3
2.3.1 flexGrow值的计算方式
当容器中有多个设置了flexGrow的组件时,剩余空间的分配遵循以下公式:
组件获得的额外空间 = 剩余空间 × (组件的flexGrow值 ÷ 所有flexGrow值之和)
在我们的案例中:
- 第一个Text的flexGrow为2
- 第二个Text的flexGrow为1
- flexGrow值之和为3
- 第一个Text获得剩余空间的2/3
- 第二个Text获得剩余空间的1/3
2.3.2 Text组件的其他属性
属性 |
值 |
作用 |
textAlign |
TextAlign.Center |
设置文本在组件内水平居中对齐 |
flexGrow |
2或1 |
设置组件在剩余空间中的扩展比例 |
2.4 Flex容器的样式设置
Flex() { // 子组件 } .width('100%') .backgroundColor(0xF0F0F0)
属性 |
值 |
作用 |
width |
'100%' |
设置Flex容器宽度占父容器的100% |
backgroundColor |
0xF0F0F0 |
设置背景色为浅灰色,区分不同区域 |
3. 底部按钮栏:固定高度与底部对齐
3.1 底部区域的整体结构
// 底部按钮栏(固定高度,底部对齐) Column({ space: 12 }) { Row({ space: 24 }) { Button('取消') .width(80) .height(40) .fontColor(0x007DFF) .border({ width: 1, color: 0x007DFF }) .borderRadius(4) Button('确定') .width(120) .height(40) .backgroundColor(0x007DFF) .fontColor(0xFFFFFF) .borderRadius(4) } } .justifyContent(FlexAlign.End) .width('100%') .height(120) .padding({ bottom: 24, left: 24, right: 24 })
3.2 Column容器属性详解
属性 |
值 |
作用 |
space |
12 |
设置子组件之间的垂直间距为12vp |
justifyContent |
FlexAlign.End |
设置子组件在垂直方向上底部对齐 |
width |
'100%' |
设置Column宽度占父容器的100% |
height |
120 |
设置Column高度为固定的120vp |
padding |
{ bottom: 24, left: 24, right: 24 } |
设置内边距:底部24vp,左右各24vp |
底部按钮栏使用了固定高度的Column容器,通过justifyContent属性设置为FlexAlign.End,确保内部的按钮行位于容器底部。这种设计在弹窗、表单等界面中非常常见,可以确保操作按钮始终位于视图底部,提高用户操作的便捷性。
3.3 Row组件:水平排列按钮
Row({ space: 24 }) { // 按钮组件 }
属性 |
值 |
作用 |
space |
24 |
设置子组件之间的水平间距为24vp |
Row组件用于水平排列子组件,在这里用于并排放置"取消"和"确定"两个按钮。通过space属性设置按钮之间的间距,使界面更加美观。
3.4 Button组件详解
3.4.1 取消按钮
Button('取消') .width(80) .height(40) .fontColor(0x007DFF) .border({ width: 1, color: 0x007DFF }) .borderRadius(4)
属性 |
值 |
作用 |
width |
80 |
设置按钮宽度为80vp |
height |
40 |
设置按钮高度为40vp |
fontColor |
0x007DFF |
设置文字颜色为蓝色 |
border |
{ width: 1, color: 0x007DFF } |
设置边框宽度为1vp,颜色为蓝色 |
borderRadius |
4 |
设置边框圆角为4vp |
取消按钮采用了镂空设计(只有边框,无背景色),这是常见的次要操作按钮样式,视觉重量较轻。
3.4.2 确定按钮
Button('确定') .width(120) .height(40) .backgroundColor(0x007DFF) .fontColor(0xFFFFFF) .borderRadius(4)
属性 |
值 |
作用 |
width |
120 |
设置按钮宽度为120vp,比取消按钮宽 |
height |
40 |
设置按钮高度为40vp |
backgroundColor |
0x007DFF |
设置背景色为蓝色 |
fontColor |
0xFFFFFF |
设置文字颜色为白色 |
borderRadius |
4 |
设置边框圆角为4vp |
确定按钮采用了填充设计(有背景色),这是常见的主要操作按钮样式,视觉重量较重,更容易吸引用户注意。
4. 布局设计规范与最佳实践
4.1 三段式布局的设计原则
原则 |
说明 |
实现方式 |
清晰的视觉层次 |
区分不同功能区域 |
使用不同的背景色、间距和对齐方式 |
合理的空间分配 |
重要内容区域获得更多空间 |
使用flexGrow属性按比例分配空间 |
一致的视觉风格 |
保持组件样式的一致性 |
统一的颜色、字体、圆角等样式 |
操作区域的可达性 |
确保按钮等操作元素易于触达 |
将操作按钮放在底部,并使用合适的大小 |
4.2 样式规范
4.2.1 间距规范
元素 |
间距 |
按钮之间 |
24vp |
按钮与容器边缘 |
24vp |
内容区域内边距 |
24vp |
4.2.2 颜色规范
元素 |
颜色值 |
颜色描述 |
主要按钮背景 |
0x007DFF |
蓝色 |
次要按钮边框 |
0x007DFF |
蓝色 |
主要按钮文字 |
0xFFFFFF |
白色 |
次要按钮文字 |
0x007DFF |
蓝色 |
中间内容区背景 |
0xF0F0F0 |
浅灰色 |
4.2.3 尺寸规范
元素 |
尺寸 |
主要按钮宽度 |
120vp |
次要按钮宽度 |
80vp |
按钮高度 |
40vp |
底部区域高度 |
120vp |
按钮圆角 |
4vp |
5. 完整代码分析
@Component export struct SafeAreaExample { build() { Column() { Column() { // 顶部内容(固定高度) Text('顶部内容') .fontSize(16) .padding(24) // 弹性填充区域(中间内容) Flex() { Text('中间内容\n弹性填充') .textAlign(TextAlign.Center) .flexGrow(2) // 父容器分配给该Text的宽度为剩余宽度的2/3 Text(' 弹性填充') .textAlign(TextAlign.Center) .flexGrow(1) // 父容器分配给该Text的宽度为剩余宽度的1/3 } .width('100%') .backgroundColor(0xF0F0F0) // 底部按钮栏(固定高度,底部对齐) Column({ space: 12 }) { Row({ space: 24 }) { Button('取消') .width(80) .height(40) .fontColor(0x007DFF) .border({ width: 1, color: 0x007DFF }) .borderRadius(4) Button('确定') .width(120) .height(40) .backgroundColor(0x007DFF) .fontColor(0xFFFFFF) .borderRadius(4) } } .justifyContent(FlexAlign.End) .width('100%') .height(120) .padding({ bottom: 24, left: 24, right: 24 }) } } } }
5.1 代码结构分析
- 组件定义:使用@Component装饰器定义SafeAreaExample自定义组件
- 外层容器:使用嵌套的Column组件创建整体布局框架
- 区域划分:将界面分为顶部内容、中间内容和底部按钮栏三个区域
- 弹性分配:在中间内容区使用flexGrow属性按2:1的比例分配空间
- 底部对齐:使用justifyContent(FlexAlign.End)实现底部按钮栏的底部对齐
- 按钮排列:使用Row组件水平排列取消和确定按钮
- 样式设置:为各个组件设置适当的样式属性,包括尺寸、颜色、边框等
5.2 链式调用的优势
HarmonyOS NEXT的ArkUI框架采用了链式调用的方式设置组件属性,这种方式有以下优势:
- 代码简洁:减少重复的组件引用,使代码更加简洁
- 可读性强:属性设置与组件定义紧密关联,易于理解
- 灵活性高:可以根据需要灵活添加或调整属性
- 开发效率:提高开发效率,减少代码量
6. 总结
通过本教程的两个部分,我们详细讲解了如何使用Column组件的垂直对齐能力(justifyContent)和弹性空间分配(flexGrow)创建结构合理的三段式布局,包括:
- Column组件的垂直对齐能力和FlexAlign枚举值的使用
- flexGrow属性的工作原理和空间分配计算方式
- 三段式布局的整体结构和各区域的实现细节
- 中间内容区的弹性空间分配实现
- 底部按钮栏的固定高度和底部对齐设计
- 布局设计规范与最佳实践