四、ArkUI界面设计3(高级布局)

此节核心:

  1. 弹性布局 Flex
  2. 定位
  3. 层叠布局

241004

1. 弹性布局 Flex

弹性布局Flex与线性布局LinearLayout主要区别:弹性布局中子组件灵活性相对较大,可自动换行。当出现子组件大小不等且每行排列数目不一时推荐使用弹性布局Flex,其他情况推荐线性布局LinearLayout。

Flex提供更加有效的方式对容器中的子组件进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。

容器默认存在主轴(主轴默认水平方向)与交叉轴,子组件默认沿主轴排列,子组件在主轴方向的尺寸成为主轴尺寸,在交叉轴方向的尺寸成为交叉轴尺寸。

1.1 Flex基本使用
//弹性容器组件Flex的基本使用
Flex(参数对象) {
⼦组件1
 ⼦组件2
 ⼦组件3
 ⼦组件N
}
1.2 布局方向 direction

在弹性布局中,容器的子组件可以按照任意方向排列(默认水平排列)。通过设置参数direction,可以决定主轴方向,从而控制子组件的排列方向。

参数direction的值:枚举FlexDirection

枚举值描述
Row主轴水平,(默认值),从起始端开始排列
RowReverse主轴水平,排列顺序与Row相反,从终点端开始排列
Column主轴垂直,从起始端开始排列,较常用
ColumnReverse主轴垂直,排列顺序与Column相反,从终点端开始排列

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column({space:10}){
      //Flex布局,默认主轴在水平方向,子组件水平排列
      Flex(){
        Text('1')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('2')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('3')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
      }
        .width('100%')
        .height(200)
        .backgroundColor(Color.Orange)

      //Flex布局,设置主轴在垂直方向,子组件垂直排列
      Flex({direction:FlexDirection.Column}){
        Text('1')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('2')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('3')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
      }
      .width('100%')
      .height(200)
      .backgroundColor(Color.Orange)

    }
      .padding(10)
  }
}

预览器效果:

1.3 主轴对齐方式 justifyContent

参数 justifyContent 的值:枚举FlexAlign;与线性布局主轴对齐方式相同。

justifyContent : FlexAlign.Start、Center、End、SpaceBetween、SpaceAround、SpaceEvenly。

1.4 交叉轴对齐方式 alignItems

参数 alignItems 的值:枚举ItemAlign

alignItems : ItemAlign.Start、Center、End、Stretch、Baseline。

子组件的alignSelf属性也可以设置子组件在父容器交叉轴的对齐格式,且会覆盖Flex布局容器中的alignItems配置。

示例代码:

@Entry
@Component
struct Index {
  build() {
    //Flex布局,主轴justifyContent、交叉轴alignItems对齐方式及alignSelf属性测试
    Column({space:10}){
      //设主轴布局方式为SpaceBetween,交叉轴居中Center,子组件Text(2)Stretch拉伸
      Flex({
        justifyContent:FlexAlign.SpaceBetween,
        alignItems:ItemAlign.Center
      }){
        Text('1')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('2')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
          .alignSelf(ItemAlign.Stretch)
        Text('3')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
      }
        .width('100%')
        .height(200)
        .backgroundColor(Color.Orange)
    }
      .padding(10)
  }
}

预览器效果:

DevEco代码上下换行快捷键:Alt+Shift+↑/↓


241005

1.5 布局换行 wrap

弹性布局分为单⾏布局和多⾏布局。默认情况下,Flex容器中的⼦元素都排在⼀条线(⼜称“轴线”)上。⼦元素尺⼨总和⼤于Flex容器尺⼨时,⼦元素尺⼨会⾃动挤压。

wrap属性控制当⼦元素主轴尺⼨之和⼤于容器主轴尺⼨时,Flex是单⾏布局还是多⾏布局。在多⾏布局时,通过交叉轴⽅向,确认新⾏排列⽅向。

参数 wrap 的值:枚举FlexWrap,默认NoWrap

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      Flex({
        wrap:FlexWrap.Wrap
      }){
        Text('1')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('2')
          .width(80)
          .height(30)
          .backgroundColor(Color.Pink)
        Text('3')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('4')
          .width(80)
          .height(30)
          .backgroundColor(Color.Pink)
        Text('5')
          .width(80)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('6')
          .width(80)
          .height(30)
          .backgroundColor(Color.Pink)
      }
      .width('100%')
      .height(200)
      .backgroundColor(Color.Orange)
    }
      .padding(10)
  }
}

预览器效果:

1.6 综合案例-阶段选择菜单

示例代码:

import { colorSpaceManager } from '@kit.ArkGraphics2D'

@Entry
@Component
struct Index {
  build() {
    Column(){
      //案例内容练习
      Column(){
        //标题
        Text('阶段选择')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .padding(10)
        //弹性布局练习
        Flex({
          //子组件自动换行
          wrap:FlexWrap.Wrap,
        }){
          //练习中Text文本内容可改可不改,重点练习布局属性及参数,后期调用数据库
          Text('ArkUI')
            .padding(10)
            .margin(5)
            .backgroundColor('#f6f7f9')
          Text('ArkTS')
            .padding(10)
            .margin(5)
            .backgroundColor('#f6f7f9')
          Text('界面开发')
            .padding(10)
            .margin(5)
            .backgroundColor('#f6f7f9')
          Text('系统能力')
            .padding(10)
            .margin(5)
            .backgroundColor('#f6f7f9')
          Text('权限控制')
            .padding(10)
            .margin(5)
            .backgroundColor('#f6f7f9')
          Text('元服务')
            .padding(10)
            .margin(5)
            .backgroundColor('#f6f7f9')
        }
      }
      .width('100%')
      .height('100%')
      .padding(10)
    }
  }
}

预览器效果:

案例中遇到问题:对padding和margin组合使用后效果不熟悉,造成自己独立完成时卡壳。

1.7 自适应拉伸
1.7.1 flexGrow

作用:设置父容器的剩余空间分配给此属性所在组件的比例。

属性flexGrow的参数为数字,即占用父级剩余尺寸的份数。

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      //flexGrow:分配父组件剩余尺寸,数字表示占用份数。
      Flex(){
        Text('1')
          .width(50)
          .height(30)
          .backgroundColor(Color.Yellow)
        Text('2')
          .height(30)
          .backgroundColor(Color.Pink)
          .flexGrow(2)
        Text('3')
          .height(30)
          .backgroundColor(Color.Yellow)
          .flexGrow(1)
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Orange)
    }
      .padding(10)
  }
}

预览器效果:

1.7.2 flexBasis

作⽤:设置⼦元素在⽗容器主轴⽅向上的基准尺⼨。flexBasis可以设置为具体的长度值(如50px、10%)或者auto。当设置为具体长度值时,它决定了项目在分配多余空间之前的基础大小。
效果:flexBasis是在弹性盒子布局(Flexbox)中使用的,它允许项目在保持一定基础大小的同时,还能根据可用空间进行伸缩。

flexBasis是设置项目的基础大小,而不是最终大小。最终大小还取决于flexGrow和flexShrink以及容器的总空间。

属性:flexBasis(数字)

参数:数字,基准尺⼨(单位vp)。

2. 定位

作用:改变组件位置。

  • 绝对定位:position,相对父组件左上角进行修改。
  • 相对定位:offset,相对自身左上角进行偏移。
2.1 绝对定位 position

position(){ x:水平偏移量, y:垂直偏移量}

偏移量取值:数字,单位为vp;百分比,参照父组件尺寸计算结果。

绝对定位特点:

  1. 参照父组件左上角进行偏移
  2. 绝对定位后的组件不再占用自身原有位置

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column({space:10}){
      //无position属性值
      Column(){
        Text('1')
          .width(50)
          .height(30)
          .backgroundColor(Color.Blue)
        Text('2')
          .width(50)
          .height(30)
          .backgroundColor(Color.Orange)
        Text('3')
          .width(50)
          .height(30)
          .backgroundColor(Color.Yellow)
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)

      //对Text('1')子组件设置position,查看对比效果
      Column(){
          Text('1')
            .width(50)
            .height(30)
            .backgroundColor(Color.Blue)
            .position({x:0,y:0})
          Text('2')
            .width(50)
            .height(30)
            .backgroundColor(Color.Orange)
          Text('3')
            .width(50)
            .height(30)
            .backgroundColor(Color.Yellow)
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)
    }
    .padding(10)
  }
}

预览器效果:

2.2 相对定位 offset

offset(){ x:水平偏移量, y:垂直偏移量}

偏移量取值:数字,单位为vp;百分比,参照父组件尺寸计算结果。

相对定位特点:

  1. 相对自身左上角进行偏移
  2. 相对定位后的组件仍然占用自身原有位置

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column({space:10}){
      //无offset属性值
      Column(){
        Text('1')
          .width(50)
          .height(30)
          .backgroundColor(Color.Blue)
        Text('2')
          .width(50)
          .height(30)
          .backgroundColor(Color.Orange)
        Text('3')
          .width(50)
          .height(30)
          .backgroundColor(Color.Yellow)
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)

      //对Text('1')子组件设置offset,查看对比效果
      Column(){
          Text('1')
            .width(50)
            .height(30)
            .backgroundColor(Color.Blue)
            .offset({x:10,y:10})
          Text('2')
            .width(50)
            .height(30)
            .backgroundColor(Color.Orange)
          Text('3')
            .width(50)
            .height(30)
            .backgroundColor(Color.Yellow)
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)
    }
    .padding(10)
  }
}

预览器效果:

2.3 案例-人气热播故事

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      //喜马拉雅-人气热播故事,简单案例自主练习
      Column(){
        //主图
        Image($r('app.media.moco'))
          .width(300)
          .borderRadius(15)
        //左上角VIP样式标识
        Text('VIP')
          .padding({
            top:3,bottom:3,left:5,right:5})
          .fontWeight(600)
          .fontColor(Color.White)
          .fontStyle(FontStyle.Italic) //斜体
          .position({
            x:0,y:0
          })
          .border({width:3,color:Color.White})
          .borderRadius({topLeft:15,bottomRight:15})
          .backgroundColor(Color.Orange)
          //遗漏,二次补齐属性
          /*.textAlign(TextAlign.Center)
          .fontSize(15)
          .width(34)
          .height(20)*/

        //下方简单介绍
        Row({space:20
        }){
          Image($r('app.media.ic_device_earphone_roc_filled'))
            .fillColor(Color.White)
            .width(40)
            .backgroundColor('#ADD8E6')
            .borderRadius(25)
            .padding(5)
          Text('飞狗MOCO')
            .fontWeight(700)
            .fontSize(28)
        }
        .padding(10)
        .width(300)
        //遗漏,二次补齐属性,交叉轴对齐方式
        .alignItems(VerticalAlign.Top)
      }
      // .borderRadius({topLeft:15,topRight:15})
      .backgroundColor(Color.White)
      .padding({left:5,right:5})
    }
    .width('100%')
    .height('100%')
    .padding(10)
    .backgroundColor('#ededed')
  }
}

预览器效果:

2.4 Z序控制 zIndex

定义后的组件,默认后定义的组件在最上面显示,可以通过zIndex属性调整显示层级。用于控制元素在页面上的层叠顺序。

zIndex(),特点:取值为整数数字;取值越大,显示层级越高。

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column({space:5}){
      //无position无zIndex
      Column(){
        Text('1')
          .width(50)
          .height(30)
          .backgroundColor(Color.Blue)
        Text('2')
          .width(50)
          .height(30)
          .backgroundColor(Color.Orange)
        Text('3')
          .width(50)
          .height(30)
          .backgroundColor(Color.Yellow)
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)

      //Text1,3有绝对定位position,无zIndex设置
      //从上到下覆盖效果为321,按Text组件顺序显示,默认"后来者居上"
      Column(){
        Text('1')
          .width(50)
          .height(30)
          .backgroundColor(Color.Blue)
          .position({x:135,y:15})
        Text('2')
          .width(50)
          .height(30)
          .backgroundColor(Color.Orange)
        Text('3')
          .width(50)
          .height(30)
          .backgroundColor(Color.Yellow)
          .position({x:165,y:20})
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)

      //Text1,3有绝对定位position,且有zIndex设置
      //从上到下覆盖效果为123,按zIndex属性值大小显示
      Column(){
        Text('1')
          .width(50)
          .height(30)
          .backgroundColor(Color.Blue)
          .position({x:135,y:15})
          .zIndex(2)
        Text('2')
          .width(50)
          .height(30)
          .backgroundColor(Color.Orange)
          .zIndex(1)
        Text('3')
          .width(50)
          .height(30)
          .backgroundColor(Color.Yellow)
          .position({x:165,y:20})
      }
      .width('100%')
      .height(100)
      .backgroundColor(Color.Pink)
    }
    .padding(5)
    .backgroundColor('#ededed')
  }
}

预览器效果:


241006

3. 层叠布局 StackLayout

层叠布局用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局。层叠布局通过Stack容器组件实现位置的固定定位与层叠,容器中的子元素依次入栈,后一个子元素覆盖前一个子元素,子元素可以叠加,也可以设置位置。

层叠布局具有较强的页面层叠、位置定位能力,其使用场景有广告、卡片层叠效果等。

3.1 基本使用

Stack组件为容器组件,容器内可包含各种子元素。其中子元素默认进行居中堆叠。子元素被约束在Stack下,进行自己的样式定义及排列。

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      //4.3.1 层叠布局,添加三个子组件,默认层叠效果显示
      //层叠效果默认后来者居上,且其默认对齐方式为center,效果居中层叠
      Stack(){
        Column(){
        }
        .width(250)
        .height(200)
        .backgroundColor(Color.Yellow)

        Text('文字')
          .width(150)
          .height(150)
          .backgroundColor(Color.Orange)

        Button('按钮')
          .width(80)
          .height(40)
      }
      .width(300)
      .height(300)
      .backgroundColor(Color.Gray)
    }
    .padding(5)
    .backgroundColor('#ededed')
  }
}

预览器效果:

3.2 对齐方式 alignContent

参数alignContent取值为枚举Alignment,前几个章节有提到过,Alignment枚举以下简单略过。

TopStart、Top、TopEnd、Start、Center、End、BottomStart、Bottom、BottonEnd。

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      //4.3.2 层叠布局,三个子组件,添加对齐方式alignContent后其层叠效果显示
      //层叠效果默认后来者居上(可添加zIndex改变默认层叠效果)
      Stack({
        //对齐方式以左下作为起始段
        alignContent:Alignment.BottomStart
      }){
        Column(){
        }
        .width(250)
        .height(200)
        .backgroundColor(Color.Yellow)

        Text('文字')
          .width(150)
          .height(150)
          .backgroundColor(Color.Orange)

        Button('按钮')
          .width(80)
          .height(40)
      }
      .width(300)
      .height(300)
      .backgroundColor(Color.Gray)
    }
    .padding(5)
    .backgroundColor('#ededed')
  }
}

预览器效果:

3.3 Z序控制 zIndex

(此节2.4)

定义后的组件,默认后定义的组件在最上面显示,可以通过zIndex属性调整显示层级。用于控制元素在页面上的层叠顺序。

zIndex(),特点:取值为整数数字;取值越大,显示层级越高。

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      //4.3.3 层叠布局,三个子组件,添加对齐方式alignContent后其层叠效果显示
      //层叠效果默认后来者居上(可添加zIndex改变默认层叠效果)
      //添加zIndex使Text组件在最上层
      Stack({
        //对齐方式以左下作为起始端
        alignContent:Alignment.BottomStart
      }){
        Column(){
        }
        .width(250)
        .height(200)
        .backgroundColor(Color.Yellow)

        Text('文字')
          .width(150)
          .height(150)
          .backgroundColor(Color.Orange)
          .zIndex(1)

        Button('按钮')
          .width(80)
          .height(40)
          //添加相对定位属性更方便查看层叠效果
          .offset({
            x:120,y:0
          })
      }
      .width(300)
      .height(300)
      .backgroundColor(Color.Gray)
    }
    .padding(5)
    .backgroundColor('#ededed')
  }
}

预览器效果:

4. 综合案例-B站视频推荐卡片

示例代码:

@Entry
@Component
struct Index {
  build() {
    Column(){
      /*布局思路:
        1.Stack容器,Image+Row(图标+文字),zIndex层叠效果
        2.Row(){Text组件,文本超长显示方式textOverflow
                Row(文字+图标)
              }
      */

      //案例B站视频推荐卡片练习
      Column(){
        //1.图片区域 Stack层叠布局
        Stack({ //层叠对齐方式,alignContent底端对齐
          alignContent:Alignment.Bottom}) {
          //视频封面
          Image($r('app.media.tieyi'))
            .width('100%')
            .height(125)
            //图片缩放
            // .objectFit(ImageFit.Contain)
            .borderRadius({topLeft:15,topRight:15})

          Row(){
            //左方播放数量及弹幕数量显示
            Row({space:5}){
              Image($r('app.media.ic_bofangshu'))
                .width(15)
                .fillColor(Color.White)
              Text('282万')
                .fontColor(Color.White)
              Image($r('app.media.ic_danmu'))
                .width(15)
                .fillColor(Color.White)
              Text('8655')
                .fontColor(Color.White)
            }
            //右方视频时长
            Text('4:33')
              .fontColor(Color.White)
          }
          .padding(5)
          .width('100%')
          //主轴对齐方式SpaceBetween
          .justifyContent(FlexAlign.SpaceBetween)
          //此效果也可用Blank()空白填充组件来实现,占用剩余空间

          // .backgroundColor(Color.Black)
        }

        //2.文字区域 Row
        Column({space:5}){
          //标题文字及简单介绍
          Text('【凤凰传奇新歌】欢迎来到国风统治区:唢呐一响神曲《铁衣》')
            .fontSize(14)
            .width('100%')
            .maxLines(2)
            .textOverflow({overflow:TextOverflow.Ellipsis})
          //点赞数量及‘更多’图标
          Row(){
            Text('19万点赞')
              .backgroundColor(Color.Pink)
              .fontSize(13)
              .fontColor(Color.Red)
              .padding(2)
            Image($r('app.media.ic_gengduo'))
              .width(15)
          }
          .width('100%')
          .justifyContent(FlexAlign.SpaceBetween)
        }
        .padding({top:8,left:5,right:5,bottom:10})
      }
      .width(200)
      .backgroundColor('#fff')
      .borderRadius(15)

    }
    .padding(10)
    .width('100%')
    .height('100%')
    .backgroundColor('#ededed')
  }
}

预览器效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值