静态布局综合案例

189 阅读4分钟

静态布局综合案例

1.凤凰传奇

17237104804031.png 思路

1.首先从整体布局看分文上下两个部分:column()

image-20240815121625463
1.对上部分图片进行分析:
1.可以看到图片中的播放了,弹幕,时间,都是显示在大图片上,这里我们首先可以考虑stack()
2.再利用stack的自带参数alignContent 进行位置调整
名称描述
TopStart顶部起始端
Top顶部横向居中
TopEnd顶部尾端
Start起始端纵向居中
Center居中(默认)
End尾端纵向居中
BottomStart底部起始端
Bottom底部横向居中
BottomEnd底部尾端
3.对这个部分进行分析:

image-20240815194049169.png 这个用画图可以更直观的体现,可以分为三个来实现:

第一部分:整体布局用Row!

image-20240815194152192.png 第二部分:将左边模块再看成一个整体,用Row进行包裹,右边看成单独整体!

image-20240815194435211.png 第三部分:在对左边整体内容进行模块划分分别用Row进行水平排列

image-20240815194527542.png

​ 最后对整体内容通过Row中主轴对齐方式:justifyContent(FlexAlign.SpaceBetween)两端对齐来实现效果

上半部分关键代码

 Column() {//调整粘贴图片位置
        Stack({ alignContent: Alignment.BottomStart }) {
        //1.主图篇
          Image($r("app.media.fenghuangchuanqi"))
            .width(360)
            .height(200)
            .objectFit(ImageFit.Cover)
            .borderRadius({
              topLeft: 15,
              topRight: 15
            })
          Row() {//2.将要粘贴至主图片上的模块看为一个整体
            Row({ space: 25 }) {
            //3.将右边部分看为一个整体
              Row({ space: 5 }) {
              //3.1右边部分一个模块
                Image($r("app.media.start"))
                  .fillColor(Color.White)
                  .width(35)
                  .height(35)
                Text("282万")
                  .fontSize(15)
                  .fontColor(Color.White)
                  .fontWeight(500)

              }

              Row({ space: 5 }) {
              //3.2右边部分第二个模块
                Image($r("app.media.DanMu"))
                  .width(30)
                  .height(30)
                  .fillColor(Color.White)


                Text("9655")
                  .fontSize(15)
                  .fontColor(Color.White)
                  .fontWeight(500)


              }
            }
            //4单独一个整体
            Text("4:33")
              .fontColor(Color.White)
          }.width("100%")
          .justifyContent(FlexAlign.SpaceBetween)//两端对齐方式
          .padding(5)

        }
      }

2.对下半部分分析:
也是分为上下两个部分,文本作为一个部分,点赞数与图片作为以一个部分

image-20240815195125355.png

这里内容比较少直接展示关键代码


      Column({ space: 10 }) {
      //1.整体布局垂直排列
        Text("【凤凰传奇新歌】欢迎来到国风统治区:唢呐一响神曲《铁衣》燃爆登场! -  由五千万逆水寒玩家票选出、众望所归的凤凰传奇,为逆水寒玩家演唱的流派推广曲《铁衣》MV正式高燃上线!")
          .maxLines(2)//文本显示最大行数
          .textOverflow({ overflow: TextOverflow.Ellipsis })//文本溢出方式
          .fontSize(23)
          .textAlign(TextAlign.Start)//文本对齐方式
          .fontWeight(500)


        Row() {
        //2.对第二个模块部分进行排列调整位置
          Text("19万点赞")
            .backgroundColor("#ffeee1d2")
            .fontColor("#c37153")
            .fontSize(20)
            .width(90)


          Image($r("app.media.point"))
            .width(30)
            .height(30)
            .fillColor("#b5b5b5")
        }.width("100%")
        .justifyContent(FlexAlign.SpaceBetween)
      }

2.智能家居

17237238366654.png 分析:

1.首先看到这样一个页面我们可以分析出页面的整体布局应该用Column实现,

2.其中在页面中我们可以发现这个模块实现了可换行的效果,所以我们可以用Flex容器,

image-20240815201250384.png

//定义一个接口
interface myMode {
  img: Resource
  name: string
}

@Entry
@Component
struct Index {
  //创建数组
  list: myMode[] = [{ img: $r("app.media.jiaju3"), name: "家居" },
    { img: $r("app.media.jiaju4"), name: "沙发" },
    { img: $r("app.media.jiaju5"), name: "VR展示" },
    { img: $r("app.media.jiaju6"), name: "定制" },
    { img: $r("app.media.jiaju7"), name: "项目" },
    { img: $r("app.media.jiaju8"), name: "设计师" },
    { img: $r("app.media.jiaju9"), name: "客服" },

    { img: $r("app.media.jiaju10"), name: "用户反馈" },

  ]

  build() {
    Flex({ wrap: FlexWrap.Wrap }) {
      //渲染数组
      ForEach(this.list, (item: myMode) => {
        Column() {
          Image(item.img)
             .width("20%")
        .margin(8)
          Text(item.name)
        }
      })
    }
  }
}

下面是Flex容器的一些属性参数介绍,方便我们更好的在实际操作中使用:

  1. Flex容器默认存在主轴交叉轴子元素默认沿主轴排列,子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸。

  2. 这是默认主轴为水平方向上的示意图

image-20240815201921176.png 3. 在Flex弹性布局中,可以通过设置参数direction,可以决定主轴的方向,来任意排列子元素的位置

| 枚举值           | 描述                                                 |
| ------------- | -------------------------------------------------- |
| Row           | 主轴为水平方向,默认值子元素从起始端沿着水平方向开始排布                       |
| RowReverse    | 主轴为水平方向子元素从终点端沿着 `FlexDirection. Row` 相反的方向开始排布    |
| **Column**    | **主轴为垂直方向**子元素从起始端沿着垂直方向开始排布                       |
| ColumnReverse | 主轴为垂直方向子元素从终点端沿着 `FlexDirection. Column` 相反的方向开始排布 |

​ 4.Flex容器可以通过设置参数wrap来实现多行排列效果

FlexWrap. NoWrap(默认值)不换行。如果子元素的宽度总和大于父元素的宽度,则子元素会被压缩宽度。
FlexWrap. Wrap换行,每一行子元素按照主轴方向排列。
FlexWrap. WrapReverse换行,每一行子元素按照主轴反方向排列

3.在最后一个模块中我们可以观察到图片最下面并未完全显示,所以可以判断出含有滚动效果,那么实现滚动效果的容器有很多,如List,Scroll,Grid,Swiper等等,这里我们先学会用Scroll来实现效果

image-20240815204956364.png

Scroll() {
    Column() {
      Row() {
        Text()
          .backgroundColor("#fff3eded")
          .width("100%")
          .height(10)
      }
      Row() {
        Row({ space: 5 }) {
          Row() {
            Text()
          }
          .backgroundColor("#80c269")
          .height(15)
          .width(3)

          Text("案例展示")
            .fontSize(15)
        }
        Row({ space: 5 }) {
          Text("更多")
            .fontSize(12)
            .fontColor("#5d5d5d")
          Button() {
            Image($r("app.media.ic_public_arrow_right"))
              .width("4%")
              .fillColor(Color.White)
          }.backgroundColor("#83c36d")
        }
      }.width("100%")
      .justifyContent(FlexAlign.SpaceBetween)
      .padding(10)

      Image($r("app.media.jiaju1"))
        .width("100%")
        .padding(10)
      Column() {
        Text("岭南林语")
          .width("100%")

        Row() {
          Text("108|两室一厅|简约")
            .fontColor("#b9b9b9")
            .fontSize(10)
          Text("总价:  ¥88000")
            .fontColor(Color.Red)
        }.width("100%")
        .justifyContent(FlexAlign.SpaceBetween)
      }.width("100%")
      .padding(10)

      Image($r("app.media.jiaju1"))
        .width("100%")
        .padding(10)
    }.height(700)//内容高度
  }.height(600)//scroll容器高度

再来学习一波scroll的基本用法吧

1.在使用Scroll之前,必须知道Scroll是可滚动的容器组件,当子组件的布局尺寸超过Scroll的尺寸时,内容可以滚动。

2.核心用法

  1. Scroll 设置尺寸

  2. 设置 子组件(只支持一个子组件)

  3. 设置滚动:

    1. 竖向滚动:子组件的高度超出 Scroll
    2. 横向滚动:子组件的宽度超出 Scroll,scrollable改为横向滚动
3.基础属性
scrollableScrollDirection设置滚动方向。ScrollDirection.Vertical 纵向ScrollDirection.Horizontal 横向
scrollBarBarState设置滚动条状态。
scrollBarColorstring | number | Color设置滚动条的颜色。
scrollBarWidthstring | number设置滚动条的宽度
edgeEffectvalue:EdgeEffect设置边缘滑动效果。EdgeEffect.None 无EdgeEffect.Spring 弹簧EdgeEffect.Fade 阴影

3.清楚了这两个模块的实现方法后,我们就可以对页面进行布局了

  1. 一共分为三个模块:

image-20240815205214603.png

  1. 在进行编码时我们应该明确的对每一个模块进行编写,最后用Column来实现页面的整体布局,这里只需要将上面的两个关键代码与第一个模块组合就可以实现图片效果了

    完整代码

    //定义一个接口
    interface myMode {
      img: Resource
      name: string
    }
    
    @Entry
    @Component
    struct Index {
      //创建数组
      list: myMode[] = [{ img: $r("app.media.jiaju3"), name: "家居" },
        { img: $r("app.media.jiaju4"), name: "沙发" },
        { img: $r("app.media.jiaju5"), name: "VR展示" },
        { img: $r("app.media.jiaju6"), name: "定制" },
        { img: $r("app.media.jiaju7"), name: "项目" },
        { img: $r("app.media.jiaju8"), name: "设计师" },
        { img: $r("app.media.jiaju9"), name: "客服" },
    
        { img: $r("app.media.jiaju10"), name: "用户反馈" },
    
      ]
    
     build() {
      Column() {
    //第一模块
        Image($r("app.media.jiaju2"))
          .width("100%")
        Flex({ wrap: FlexWrap.Wrap }) {
            //第二模块
          //渲染数组
          ForEach(this.list, (item: myMode) => {
            Column() {
              Image(item.img)
                 .width("20%")
            .margin(8)
              Text(item.name)
            }
          })
        }
          Scroll() {//第三模块
        Column() {
          Row() {
            Text()
              .backgroundColor("#fff3eded")
              .width("100%")
              .height(10)
          }
          Row() {
            Row({ space: 5 }) {
              Row() {
                Text()
              }
              .backgroundColor("#80c269")
              .height(15)
              .width(3)
    
              Text("案例展示")
                .fontSize(15)
            }
            Row({ space: 5 }) {
              Text("更多")
                .fontSize(12)
                .fontColor("#5d5d5d")
              Button() {
                Image($r("app.media.ic_public_arrow_right"))
                  .width("4%")
                  .fillColor(Color.White)
              }.backgroundColor("#83c36d")
            }
          }.width("100%")
          .justifyContent(FlexAlign.SpaceBetween)
          .padding(10)
    
          Image($r("app.media.jiaju1"))
            .width("100%")
            .padding(10)
          Column() {
            Text("岭南林语")
              .width("100%")
    
            Row() {
              Text("108|两室一厅|简约")
                .fontColor("#b9b9b9")
                .fontSize(10)
              Text("总价:  ¥88000")
                .fontColor(Color.Red)
            }.width("100%")
            .justifyContent(FlexAlign.SpaceBetween)
          }.width("100%")
          .padding(10)
    
          Image($r("app.media.jiaju1"))
            .width("100%")
            .padding(10)
          }.height(700)
        }.height(600)
      }.width("100%")
       .height("100%")
     }
    }