基础布局

1.相对布局 (RelativeContainer)

1.1 基本概念

RelativeContainer为相对布局的容器,支持容器内部的子元素设置相对位置关系,适用于界面复杂场景的情况。
在这里插入图片描述
使用相对布局,需要搞清楚下面两个概念
● 锚点:通过锚点设置当前元素基于哪个元素确定位置。
● 对齐方式:通过对齐方式,设置当前元素是基于锚点的上中下对齐,还是基于锚点的左中右对齐。
如下图所示,红色方块Row相对于父容器RelativeContainer的位置可以通过指定的锚点对其方式来设定。
左图:
● Row的左边框与RelativeContainer的左边框对齐,此时RelativeContainer的左边框就是一个锚点
● Row的上边框与RelativeContainer的上边框对齐,此时RelativeContainer的上边框就是一个锚点
右图:
● Row的下边框与RelativeContainer的下边框对齐,此时RelativeContainer的下边框就是一个锚点
● Row的右边框与RelativeContainer的有边框对齐,此时RelativeContainer的有边框就是一个锚点

在这里插入图片描述

1.2 相对父容器定位

如下图所示,最外层蓝色的方框是一个RelativeContainer,然后相对于该容器,放置4个带颜色的小方块在不同的位置。
如图:第一个绿色小方块相对于父容器的对齐方式,其他组件依此内推。
在这里插入图片描述
完整代码如下:RelativeContainer容器组件的id默认为"container",每个组件的相对位置都是以
"container"为锚点

@Entry
@Component
struct Index {
  build() {
    Row() {
      RelativeContainer() {
        Row()
          .id("row1")
          .width(100)
          .height(100)
          .backgroundColor(Color.Green)
          .alignRules({
            top: { anchor: "__container__", align: VerticalAlign.Top },
            left: { anchor: "__container__", align: HorizontalAlign.Start }
          })

        Row()
          .id("row2")
          .width(100)
          .height(100)
          .backgroundColor(Color.Brown)
          .alignRules({
            top: { anchor: "__container__", align: VerticalAlign.Top },
            right: { anchor: "__container__", align: HorizontalAlign.End }
          })

        Row()
          .id("row3")
          .width(100)
          .height(100)
          .backgroundColor(Color.Orange)
          .alignRules({
            bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
            left: { anchor: "__container__", align: HorizontalAlign.Start }
          })

        Row()
          .id("row4")
          .width(100)
          .height(100)
          .backgroundColor(Color.Blue)
          .alignRules({
            bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
            right: { anchor: "__container__", align: HorizontalAlign.End }
          })
        })
      }
      .width(300).height(300)
      .margin({ left: 50 })
      .border({ width: 2, color: "#6699FF" })
    }
    .height('100%')
  }
}

1.3 子组件位置偏移

接下来我想在蓝色方框的中间位置放置一个红色方块,按照前面学习的对齐方式采用水平居中、垂直居中对齐。
● 理想效果是这样的

在这里插入图片描述

@Entry
@Component
struct Index {
  build() {
    Row() {
      RelativeContainer() {
        //....
        //想要居中对齐的组件
        Row()
          .id("row5")
          .width(100)
          .height(100)
          .backgroundColor(Color.Red)
          .alignRules({
            //上边框与父组件中线居中
            top: { anchor: "__container__", align: VerticalAlign.Center },
            //左边框与父组件中线居中
            left: { anchor: "__container__", align: HorizontalAlign.Center }
          })
      }
      .width(300).height(300)
      .border({ width: 2, color: "#6699FF" })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}
  • 但是实际效果是这样的
    在这里插入图片描述
    此时需要对子组件进行位置偏移,使用offset属性进行位置偏移。 注意:坐标轴的方向,x轴正方向向右,y轴正方向向下。
    哈哈,效果达到了
    在这里插入图片描述

1.4 相对兄弟组件定位

如果RelativeContainer父容器看作是父亲,那么里面的子组件就是儿子,同级别的多个子组件就是兄弟关系。
在这里插入图片描述
注意:相对于兄弟组件定位,必须给兄弟组件设置一个id值,否则找不到兄弟组件,会导致组件显示不了。

RelativeContainer() {
  Row().id('row6').width(100).height(100).backgroundColor(Color.Green)

  Row().id('row7').width(100).height(100).backgroundColor(Color.Brown)
    .alignRules({
      left: {anchor:'row6',align:HorizontalAlign.End},
      top:{anchor: 'row6',align:VerticalAlign.Bottom}
    })

}.width(300).height(300)
.border({ width: 2, color: "#6699FF" })

2.滚动容器(Scroll)

2.1 核心用法

在ArkUI中,使用Scroll表示可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。

📢 注意:Scorll使用时有以下两个注意点

  1. Scroll 有且只能包含一个子组件
  2. Scroll 子组件的布局尺寸大于父组件的尺寸时,才可以滚动。

在这里插入图片描述
代码展示

@Entry
@Component
struct Index {
  scroller:Scroller = new Scroller()
  build() {
    Column() {
      Row()
        .width('100%')
        .height(50)
        .backgroundColor(Color.Red)

      Scroll(){
        Column({space:10}) {
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
          Text("滚动区域内容").width('100%').height(60).textAlign(TextAlign.Center).backgroundColor(Color.Pink)
        }
        .width('100%')
        .backgroundColor(Color.Orange)
      }.layoutWeight(1)
      .scrollBar(BarState.On)   //打开滚动条
      .scrollable(ScrollDirection.Vertical) //滚动方向
      .scrollBarWidth(20) //滚动条宽度
      .scrollBarColor(Color.Red)  //滚动条颜色

      Row()
        .width('100%')
        .height(50)
        .backgroundColor(Color.Blue)
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width('100%')
    .height('100%')
  }
}

3. 栅格布局(GridRow)

3.1 基本概念

栅格布局可以在不同的设备上自适应排版,使得页面布局更加灵活和适应性更强。当页面元素的数量超出了一行或一列的容量时,他们会自动换到下一行或下一列。
GridRow为栅格容器组件,需与栅格子组件GridCol在栅格布局场景中联合使用。栅格系统以屏幕宽度为依据,把屏幕分为若干个列,每一个栅格子可以横跨指定的列从而完成组件的定位和布局。
在这里插入图片描述

3.2 栅格系统的总列数

栅格系统的总列数可以使用默认值(12列),也可以自己指定列数,还可以根据屏幕的宽度动态调整列数。

3.2.1 默认栅格列数

在这里插入图片描述

@Entry
@Component
struct Index {
  build() {
    GridRow() {
      GridCol() {
        Row() {
          Text('1')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('2')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('3')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('4')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('5')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('6')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('7')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('8')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('9')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('10')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('11')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      GridCol() {
        Row() {
          Text('12')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }
    }.height(300).backgroundColor(Color.Pink)
  }
}
3.2.2 指定栅格列数

通过GridRow的{columns:6}参数可以指定栅格总列数。比如下面案例中,栅格总列数为6,一共12个栅格子,那么一行就是6个,超过一行的部分自动换行。
在这里插入图片描述

@Entry
@Component
struct Index {
  build() {
    GridRow({ columns: 6 }) {
      GridCol() {
        Row() {
          Text('1')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }

      //...中间省略了10个栅格子GridCol(),包括上下两个栅格子,一共12个栅格子
       
      GridCol() {
        Row() {
          Text('12')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }
    }.height(300).backgroundColor(Color.Pink)
  }
}
3.2.3 动态调整列数

为了适应不同屏幕尺寸下的布局,栅格系统的总列数可以根据不同的屏幕尺寸动态调整。
在这里插入图片描述
要实现动态调整列数,这里需要引入一个概念叫做栅格系统断点。

栅格系统断点
是指在响应式设计中,用于控制页面布局变化的一系列特定数值点。这些数值点基于设备的屏幕宽度来设定,当屏幕宽度达到或超过某个断点时,页面的布局或组件的排列方式会相应地发生调整,以适应不同尺寸的屏幕。

如下图所示:把这条直线看作屏幕的宽度,上面的5个数值点就是断点,5个断点把屏幕宽度分为6个区间,对应6种设备宽度。(当然这个断点的数值也是可以自己设定的)

在这里插入图片描述
不同屏幕尺寸的设备,就是依靠断点进行区分的,如下表
在这里插入图片描述
如下代码:根据断点设备设置栅格总列数

GridRow({
    //设置对应断点设备的总列数
    columns: {
      xs: 3,		//最小宽度型设备3列
      sm: 6,		//小宽度设备6列
      md: 8,		//中型宽度设备8列
      lg: 12		//大型宽度设备12列
    },
    //设置断点
    breakpoints: {
      value: ['320vp', '520vp', '840vp', '1080vp', '1920vp']
    }
  }){
    //GridCol栅格子组件....
  }

3.3 栅格子占用列数

通过设置GridCol传参{span:3}来设置栅格子占用的列数。比如我们想要的效果如下。
在这里插入图片描述

@Entry
@Component
struct Index {
  build() {
    GridRow({columns: 6) {
      //第1个栅格
      GridCol({ span: 3 }) {
        Row() {
          Text('1')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }
      //...中间省略了第2,3,4个栅格子
      //第5个栅格子
      GridCol({span:6}) {
        Row() {
          Text('5')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }
      //...中间省略了第6个栅格子
      //第7个栅格子
      GridCol({ span: 4 }) {
        Row() {
          Text('7')
        }
        .width('100%')
        .height(50)
        .border({ width: 1, color: Color.Black, style: BorderStyle.Solid })
        .justifyContent(FlexAlign.Center)
      }
      //...这里省略了第8,9,10,11,12个栅格子
      
    }.height(300).backgroundColor(Color.Pink)
  }
}

3.4 栅格间距

通过GridRow的{gutter: 10} 参数可以调整栅格子之间的间距,默认为0。

GridRow({
  columns: 6
  gutter: 10
}){
  //GridCol栅格子
}

在这里插入图片描述

4.Grid 网格布局

ArkUI提供了Grid容器组件和子组件GridItem,用于构建网格布局。Grid用于设置网格布局相关参数,GridItem定义子组件相关特征。

4.1 基本使用

如同所示,显示一个3行3列的网格,每一个单元格中显示一个数字。
在这里插入图片描述

@Entry
@Component
struct GridPage1 {
  @State numbers: number[] = []

  onPageShow(): void {
    for (let index = 0; index < 10; index++) {
      this.numbers.push(index)
    }
  }

  build() {
    Column() {
      Grid() {
        ForEach(this.numbers, (item: number, index: number) => {
          GridItem() {
            Text(`${item}`).textAlign(TextAlign.Center).width("100%").height(50).backgroundColor(Color.Yellow)
          }
        })
      }
      .width("100%")
      .height(200) //Grid 如果没有设置宽高,则自适应父组件宽高
      .backgroundColor(Color.Pink)
      .columnsTemplate("1fr 1fr 1fr") //列数
      .rowsTemplate("1fr 1fr 1fr") //行数
      .rowsGap(10) //行间距
      .columnsGap(10) //列间距
    }
    .width("100%")
    .height("100%")
  }
}

鸿蒙学习地址

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐