项目已开源,开源地址: 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的区别

特性FlexColumn
默认方向水平方向垂直方向
主轴默认为水平方向垂直方向
交叉轴默认为垂直方向水平方向
适用场景需要在一行内灵活分配空间需要垂直排列组件

在这个案例中,我们使用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组件的其他属性

属性作用
textAlignTextAlign.Center设置文本在组件内水平居中对齐
flexGrow2或1设置组件在剩余空间中的扩展比例

2.4 Flex容器的样式设置

Flex() {
    // 子组件
}
.width('100%')
.backgroundColor(0xF0F0F0)
属性作用
width'100%'设置Flex容器宽度占父容器的100%
backgroundColor0xF0F0F0设置背景色为浅灰色,区分不同区域

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容器属性详解

属性作用
space12设置子组件之间的垂直间距为12vp
justifyContentFlexAlign.End设置子组件在垂直方向上底部对齐
width'100%'设置Column宽度占父容器的100%
height120设置Column高度为固定的120vp
padding{ bottom: 24, left: 24, right: 24 }设置内边距:底部24vp,左右各24vp

底部按钮栏使用了固定高度的Column容器,通过justifyContent属性设置为FlexAlign.End,确保内部的按钮行位于容器底部。这种设计在弹窗、表单等界面中非常常见,可以确保操作按钮始终位于视图底部,提高用户操作的便捷性。

3.3 Row组件:水平排列按钮

Row({ space: 24 }) {
    // 按钮组件
}
属性作用
space24设置子组件之间的水平间距为24vp

Row组件用于水平排列子组件,在这里用于并排放置"取消"和"确定"两个按钮。通过space属性设置按钮之间的间距,使界面更加美观。

3.4 Button组件详解

3.4.1 取消按钮

Button('取消')
    .width(80)
    .height(40)
    .fontColor(0x007DFF)
    .border({ width: 1, color: 0x007DFF })
    .borderRadius(4)
属性作用
width80设置按钮宽度为80vp
height40设置按钮高度为40vp
fontColor0x007DFF设置文字颜色为蓝色
border{ width: 1, color: 0x007DFF }设置边框宽度为1vp,颜色为蓝色
borderRadius4设置边框圆角为4vp

取消按钮采用了镂空设计(只有边框,无背景色),这是常见的次要操作按钮样式,视觉重量较轻。

3.4.2 确定按钮

Button('确定')
    .width(120)
    .height(40)
    .backgroundColor(0x007DFF)
    .fontColor(0xFFFFFF)
    .borderRadius(4)
属性作用
width120设置按钮宽度为120vp,比取消按钮宽
height40设置按钮高度为40vp
backgroundColor0x007DFF设置背景色为蓝色
fontColor0xFFFFFF设置文字颜色为白色
borderRadius4设置边框圆角为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 代码结构分析

  1. 组件定义:使用@Component装饰器定义SafeAreaExample自定义组件
  2. 外层容器:使用嵌套的Column组件创建整体布局框架
  3. 区域划分:将界面分为顶部内容、中间内容和底部按钮栏三个区域
  4. 弹性分配:在中间内容区使用flexGrow属性按2:1的比例分配空间
  5. 底部对齐:使用justifyContent(FlexAlign.End)实现底部按钮栏的底部对齐
  6. 按钮排列:使用Row组件水平排列取消和确定按钮
  7. 样式设置:为各个组件设置适当的样式属性,包括尺寸、颜色、边框等

5.2 链式调用的优势

HarmonyOS NEXT的ArkUI框架采用了链式调用的方式设置组件属性,这种方式有以下优势:

  1. 代码简洁:减少重复的组件引用,使代码更加简洁
  2. 可读性强:属性设置与组件定义紧密关联,易于理解
  3. 灵活性高:可以根据需要灵活添加或调整属性
  4. 开发效率:提高开发效率,减少代码量

6. 总结

通过本教程的两个部分,我们详细讲解了如何使用Column组件的垂直对齐能力(justifyContent)和弹性空间分配(flexGrow)创建结构合理的三段式布局,包括:

  1. Column组件的垂直对齐能力和FlexAlign枚举值的使用
  2. flexGrow属性的工作原理和空间分配计算方式
  3. 三段式布局的整体结构和各区域的实现细节
  4. 中间内容区的弹性空间分配实现
  5. 底部按钮栏的固定高度和底部对齐设计
  6. 布局设计规范与最佳实践

全栈若城
1 声望2 粉丝