Stack层叠布局及案例【华为根技术】

举报
tea_year 发表于 2025/06/13 16:43:08 2025/06/13
【摘要】 http://product.m.dangdang.com/29819440.html?t=1734349177Stack组件总结: 应用场景:1. 当当网商品详情页顶部导航, 底部导航,2. 茶窝网弹窗广告淘小说文章页顶部的字号,颜色设置面板层叠布局层叠布局(StackLayout)用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局。层叠布局通过Stack容器组件实现位置的...

http://product.m.dangdang.com/29819440.html?t=1734349177
  1. Stack组件

总结: 应用场景:
1. 当当网商品详情页顶部导航, 底部导航,
2. 茶窝网弹窗广告
  1. 淘小说文章页顶部的字号,颜色设置面板

层叠布局

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

Stack的理解

1. Stack可以是页面根元素,也可以是其中一个子元素 2. 当Stack为一个子元素时,它的位置位于上一个兄弟元素的下方 3. Stack默认的宽高为内容的宽高, 默认居中 4. Stack内部的子元素默认垂直居中,水平居中,并相互堆叠 5. 对齐方式: Stack组件通过alignContent参数实现位置的相对移动。如图2所示,支持九种对齐方式。 6. Stack容器中兄弟组件显示层级关系可以通过Z序控制的zIndex属性改变。
@Entry
@Component
struct Test{
  build(){
    Stack({alignContent: Alignment.TopStart}){
      Text('顶部导航').zIndex(100)
      Column(){}
    }
    .width('100%').height('100%').border({width: 1, color: '#f00'})
  }
}

案例一:

@Entry
@Component
struct StackSample {
  // 交互效果
  @State isShow: boolean = false

  build() {

    // Stack案例1
    // Stack({
    //   // alignContent: Alignment.TopStart,
    //   // alignContent: Alignment.Top,
    //   // alignContent: Alignment.TopEnd,
    //   // alignContent: Alignment.Start, // 垂直居中,水平左对齐
    //   // alignContent: Alignment.Center,
    //   // alignContent: Alignment.End,
    //   // alignContent: Alignment.BottomStart,
    //   // alignContent: Alignment.Bottom,
    //   alignContent: Alignment.BottomEnd
    // }){
    //   Row(){}.width('80%').backgroundColor('#f00').height(400).margin(10)
    //   Row(){}.width('60%').backgroundColor('#0f0').height(200).margin({right: 50})
    //   Row(){}.width('30%').backgroundColor('#00f').height(100)
    // }
    // .border({width: 5, color: '#000'})

    Column() {
      Stack() {
        // Stack的子组件可以设置zIndex属性,来决定叠加顺序
        Text('aaaa').width(400).backgroundColor(Color.Blue).height(80).zIndex(2)
        Text('bbbb').width(400).backgroundColor(Color.Brown).height(100)
      }
      .border({ width: 5, color: '#000' })
      .width('100%')
      .height(200)

      Stack() {
        Text('aaaa').width(400).backgroundColor(Color.Blue).height(80)
      }
      .border({ width: 5, color: '#f00' })
      .width('100%')
      .height(200)
    }

  }
}

系统图标

系统图标链接地址
// 返回箭头 <
SymbolGlyph($r('sys.symbol.chevron_left'))
  .margin({ right: 15 })
  .fontSize(20)
  
// 向右箭头 >
SymbolGlyph($r('sys.symbol.chevron_right'))

Divider组件

提供分隔器组件,分隔不同内容块/内容元素。
Divider()
  .color('#f00')
  .strokeWidth(30)
  .width(100)
  .lineCap(LineCapStyle.Round)

竖线效果

Divider()
  .color(Color.Black)
  .strokeWidth(3)
  .vertical(true)
  .height(30)

Span组件

Span组件必须嵌入在Text组件中才能显示,单独的Span组件不会呈现任何内容。
Text(){
  Span("当当自营")
  Span("书名")
}

Blank()组件

空白填充组件,在容器主轴方向上,空白填充组件具有自动填充容器空余部分的能力。
Row(){
    Text("风向热门")
      .fontSize(16)
      .fontWeight(700)
        // 显示其中一个边框
      .border({
        width: { left: 3 },
        color: '#000',
        style: { left: BorderStyle.Solid }
      })
      .padding({left: 20})

    Blank()

    Text("查看更多")
      .fontSize(12)
      .fontColor('#aaa')

    SymbolGlyph($r("sys.symbol.chevron_right"))
}
.width('100%')
.height(40)
.border({ width: 1, color: '#f00' })

Counter()组件

  //value用来计数,初始化的值是1
  @State value: number = 1

   ...
 
  Counter() {
    // 减号和加号中间显示的文本
    // 因为Text的内容必须是字符串型,而value是number型,所以用toString()把number类型转为字符串类型
    Text(this.value.toString())
  }
  
  // 当单击加号时
  .onInc(() => {
    this.value++
  })
  // 当单击减号时
  .onDec(() => {
    this.value--
  })


// xxx.ets
@Entry
@Component
struct CounterExample {
  // State状态 (响应式数据), 当数据发生变化时,触发视图更新
  @State value: number = 0

  build() {
    Column() {
      Counter() {
        Text(this.value.toString())
      }
      // 监听数值增加事件
      .onInc(() => {
        //是常用的测试代码,会在控制台(日志)打印结果, 只支持字符串型的参数
        // console.log('增加一次')

        //当有多个运算时,赋值一定是最后执行
        // this.value = this.value + 1

        //下面的代码等价于上面的那一行
        // 也就是自身加一
        this.value++
      })
      // 监听数值减少事件。
      .onDec(() => {
        console.log('减少一次')
        // 下面的代码等价于   this.value = this.value - 1
        // this.value--

        // 如果if后面的条件成立,则执行{}中的逻辑,如果不成立,则不执行
        if (this.value > 0) {
          this.value--
        }
      })
      .margin(100)
    }.width("100%")
  }
}


// xxx.ets
@Entry
@Component
struct CounterExample {
  // State状态 (响应式数据), 当数据发生变化时,触发视图更新
  @State value: number = 0

  build() {
    Column() {
      Counter() {
        Text(this.value.toString())
      }
      // 监听数值增加事件
      .onInc(() => {
        this.value++
      })
      // 监听数值减少事件。
      .onDec(() => {
       this.value --
      })
      // .enableDec(this.value > 0 ? true: false)

      // 大于运算符执行的结果就是布尔值,条件成立,是true, 条件不成立,是false
      .enableDec(this.value > 0)
      .margin(100)
    }.width("100%")
  }
}

backgroundImage属性


//设置背景图片和是否重复
.backgroundImage('图片地址',ImageRepeat.X)

//背景图片的尺寸
.backgroundImageSize({
  width: 50,
  height: 30
})
//背景图片的位置 
.backgroundImagePosition({
  x: 10,
  y: 10
})

Rating评分组件

//默认样式
Rating({
  rating: 3.5,  //评分
})

//
Column() {

  // rating代表评分
  // indicator: 为true时,只能显示,不能打分, 为false时,可以评分
  Rating({ rating: this.rating, indicator: false })
    .stars(6)  //所有星的个数
    .stepSize(0.5)  // 设置操作评级的步长
    .margin({ top: 24 })
    
    //当评分发生改变时
    .onChange((value: number) => {
      console.log(value.toString())
      this.rating = value
    })

  Text(`当前的评分是: ${this.rating}`)
}.width("100%")

ainbow Brackets插件

让你的括号变成不一样的颜色,防止错乱括号
【文件菜单】【设置】【插件】【搜索该插件】【安装】效果如下:

顶部导航的切换效果

@Entry
@Component
struct Del {
  @State navList: string[] = ['商品','详情','评论','推荐']
  @State currentIndex: number = 3
  build() {
    Column() {
      //顶部的三个区域的布局
      // Row() {
      //   Text("返回")
      //   Row() {
      //     Text("商品")
      //     Text("商品")
      //     Text("商品")
      //     Text("商品")
      //   }
      //
      //   Text("点")
      // }
      // .justifyContent(FlexAlign.SpaceEvenly)
      // .width('100%')
      //
      // // .border({width: 1, color: '#f00'})
      // Flex({
      //   justifyContent: FlexAlign.SpaceEvenly
      // }){
      //   Text("商品1").border({width: 1, color: '#f00'}).width("30%")
      //   Text("商品2").border({width: 1, color: '#f00'}).width("30%")
      //   Text("商品3").border({width: 1, color: '#f00'}).width("30%")
      //   Text("商品4").border({width: 1, color: '#f00'}).width("30%")
      //   Text("商品4").border({width: 1, color: '#f00'}).width("30%")
      // }
      // .width('100%')
      // ['商品','详情','评论','推荐']
      Flex() {
        ForEach(this.navList,(item:string,index: number)=>{
          Column() {
            Text(item)
            Divider()
              .color('#f00')
              .strokeWidth(2)
              .width('60%')
              .visibility(this.currentIndex === index ? Visibility.Visible : Visibility.Hidden)
          }
          .border({ width: 1, color: '#00f' })
          // 当单击时
          .onClick(()=>{
             this.currentIndex = index
          })
        },(item:string)=>item)
      }
      .border({ width: 1, color: '#0f0' })
    }
  }
}

顶部导航的显示和隐藏效果

@Entry
@Component
struct StackSample {
  // 交互效果
 @State isShow: boolean = false

  build() {
    Column() {
      //顶部固定
      Column() {
        // ----------------------------------------------- 顶部导航
        Row() {
          Text("商品")
          Text("详情")
          Text("控制显示隐藏")
            // 只有单击时才执行
            .onClick(()=>{
              // ! 是TS中的逻辑运算符,
              // !右边如果是true, 则执行了!后,结果变为false
              // !右边如果是false, 则执行了!后,结果变为true
              this.isShow = !this.isShow
            })
        }
        .border({ width: 1, color: '#f00' })
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        //-------------------------------------------------- 可以隐藏的部分
        Row() {
          Text("可以隐藏的部分")
        }
        // .border({ width: 1, color: '#0f0' })
        .height(this.isShow ? 40 : 0)

      }.backgroundColor('#aaa').width('100%')
      // .margin({ bottom: 100 })

      Scroll() {
        Column() {
          Text("aaa").backgroundColor(Color.Brown).width('100%').height(16)
          Text("bbb").backgroundColor(Color.Grey).width('100%').height(400)
          Text("ccc").backgroundColor(Color.Blue).width('100%').height(500)
          Text("ddddd").backgroundColor(Color.Brown).width('100%').height(16)
        }
      }
    }
  }
}

当当自营的效果实现

Text(){
  Span("当当自营")
    .textBackgroundStyle({
      color: Color.Red,
      radius: 5
    })
    .fontColor('#fff')
  Span("百年孤独(同名电视剧热播,诺奖得主马尔克斯代表作,魔幻现实主义经典,赠发行超1200万纪念阅读手册)")
}

总结

通过本章节的技术学习,深入掌握了华为鸿蒙开发的各类组件技术,为后续深入进行鸿蒙开发打下了扎实的技术基础。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。