鸿蒙核心组件与进阶(1)

786 阅读4分钟

一、Swiper、Scroll

1、Swiper

先看华为官方文档的解释:滑块视图容器,提供子组件滑动轮播显示的能力。 Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示

用法

  1. 轮播内容:内容作为Swiper的子组件即可
  2. 尺寸:
    (1)设置 Swiper 的尺寸:内容会拉伸为和 Swiper 一致(优先级高)
    (2)设置内容尺寸:会将Swiper撑开
Swiper() {
  //轮播内容
  Text('0')
    .textAlign(TextAlign.Center)//文字居中显示
    .fontColor('#fff')//字体颜色白色
    .backgroundColor('#000') //背景颜色为黑色
  Text('1')
    .textAlign(TextAlign.Center)//文字居中显示
    .fontColor('#fff')//字体颜色白色
    .backgroundColor('#f00') //背景颜色为红色
}
//设置Swiper尺寸
.width('100%')
.height('50%')

属性

设置内容和尺寸后就能实现轮播啦,接下来看看常用属性

参数名参数类型参数描述
loopboolean是否开启循环 。默认值:true
autoPlayboolean子组件是否自动播放 。默认值:false
intervalnumber自动播放时的时间间隔 。默认值:3000毫秒
verticalboolean是否为纵向滑动。默认值:false
indicatorDotIndicator DigitIndicator boolean设置导航点样式,DotIndicator圆点指示器样式,DigitIndicator数字指示器样式,默认值:DotIndivator。boolean指示器是否显示,默认值:false.

案例--手机淘宝

image.png

@State swiper_tb: Resource[] = [
  $r('app.media.ic_swiper_tb01'),
  $r('app.media.ic_swiper_tb02'),
  $r('app.media.ic_swiper_tb03'),
  $r('app.media.ic_swiper_tb04'),
]

build() {
  // 手机淘宝
  Swiper() {
    ForEach(this.swiper_tb, (item: Resource) => {
      Image(item)
        .width('100%')
        .height(160)
    })
  }
  .width(171)
  .height(250)
  .margin(100)
  .borderRadius(10)
  .loop(true)
  .autoPlay(true)
  // .duration(3000)
  .interval(1000)
  .indicator(
    Indicator.dot()//圆点指示器
      .selectedColor(Color.Orange)//指示器被选中的颜色
      // .selectedItemWidth(6)//指示器被选中的宽度
        // .selectedItemHeight(6)//指示器被选中的高度
      .itemWidth(6)//指示器的宽度
      .itemHeight(6)//指示器的高度
    // Indicator.digit()//数字指示器
    //   .selectedFontColor('#fff')
  )
  //.indicator(false) //不显示指示器
}

控制器

除此之外,我们还可以通过控制器来控制轮播切换

  1. 创建一个控制器对象,
  2. 绑定给swiper,注意:一个控制器对象绑定一个swiper,多次绑定只生效最后一个
  3. 调用控制器方法
@Entry
@Component
struct taobao {
//1.创建一个控制器对象
  tb_controller: SwiperController = new SwiperController()
  
  @State swiper_tb: Resource[] = [
    $r('app.media.ic_swiper_tb01'),
    $r('app.media.ic_swiper_tb02'),
    $r('app.media.ic_swiper_tb03'),
    $r('app.media.ic_swiper_tb04'),
  ]

  build() {
    Column() {
      //  2.绑定给Swiper
      Swiper(this.tb_controller) {
        ForEach(this.swiper_tb, (item: Resource) => {
          Image(item)
            .width('100%')
            .height(160)
        })
      }
      .width(171)
      .height(250)
      .margin(100)
      .borderRadius(10)
      .loop(true)
      .autoPlay(true)
      // .duration(3000)
      .interval(1000)
      .indicator(
        Indicator.dot()//圆点指示器
        //指示器的属性;颜色、宽度、高度,被选中的宽度,被选中的高度、被选中的颜色等
          .selectedColor(Color.Orange)
          // .selectedItemWidth(6)
            // .selectedItemHeight(6)
          .itemWidth(6)
          .itemHeight(6)
        // Indicator.digit()//数字指示器
        //   .selectedFontColor('#fff')
      )
      // .indicator(false) //不显示指示器
      
      //3.定义两个按钮,调用控制器的方法控制页面切换
      Text('上一页')
        .onClick(() => {
          this.tb_controller.showPrevious()
        })
      Text('下一页')
        .onClick(() => {
          this.tb_controller.showNext()
        })
    }
    .width('100%')
    .height('100%')
  }
}

2.Scroll

依然先看华为官方文档的解释:可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。Scroll常用于固定容器可以滚动时,只能有一个子组件。

用法

常和column{}搭配使用,可以竖向滚动(子组件的高度超出 Scroll)也可以横向滚动(子组件的宽度超出 Scroll,scrollable改为横向滚动),根据实际需求来调整属性。

Scroll() {
  // 只支持一个子组件
  Column() {
    // 内容放在内部
    // 尺寸超过 Scroll 即可滚动
  }
  .width('80%')
  .height(600)
  .backgroundColor(Color.Blue)
}
.width('100%')
.height(300)
.backgroundColor(Color.Orange)

属性

参数名参数类型参数描述
scrollableScrollDirection设置滚动方向。ScrollDirection.Vertical 纵向ScrollDirection.Horizontal 横向 默认:纵向
scrollBarBarState设置滚动条状态。BarState.off 使滚动条不显示
scrollBarColorstring number Color设置滚动条颜色
scrollBarWidthstring number设置滚动条的宽度
edgeEffectvalue:EdgeEffect设置边缘滑动效果。EdgeEffect.None 无 EdgeEffect.Spring 弹簧EdgeEffect.Fade 阴影
Scroll() {
  Column() {
    //任意三张图片加起来的高度大于父组件column的高度就可滚动
    Image($r('app.media.ic_xiaomi_scroll_01'))
    Image($r('app.media.ic_xiaomi_scroll_02'))
    Image($r('app.media.ic_xiaomi_scroll_03'))
  }
  .width('100%')
}
.width('100%')
.height('100%')
.scrollable(ScrollDirection.Horizontal)//改成水平滚动
.scrollBarColor(Color.Orange) //滚动条颜色
.scrollBarWidth(20) //滚动条宽度
.scrollBar(BarState.Off) // 关闭滚动条
.edgeEffect(EdgeEffect.Fade) // 边缘效果为阴影
.edgeEffect(EdgeEffect.Spring) // 边缘效果为弹簧
控制器

Scroll和Swiper一样,也可能需要用代码控制滚动,以及获取滚动的距离

  1. 实例化 Scroller的 控制器
  2. 绑定给 Scroll
  3. 调用 控制器的方法控制滚动,通过控制器的属性获取滚动距离

我们先了解一下onWillScroll事件,由scroll组件提供,让开发者可以在适当的时候添加逻辑。

image.png 废话不多说,上案例:

image.png 需求:

  1. 静态布局,三张图片填充,火箭始终在右下角
  2. 点击火箭(ic_jd_rocket)返回顶部
  3. 火箭显示效果切换:
  • 默认隐藏
  • 滚动距离超过 400 显示
  • 滚动距离小于 400 隐藏

参考代码

@Entry
@Component
struct jd {
  //实例化控制器
  sc: Scroller = new Scroller()
  //用一个@State(响应式:动态实时变化的)变量控制小火箭的显隐,
  @State showRocket: boolean = false

  build() {
    Column() {
      //层叠布局,小火箭在右下角显示
      Stack({ alignContent: Alignment.BottomEnd }) {
        // 顶部滚动区域 控制器绑定到Scroll
        Scroll(this.sc) {
          Column() {
            //3张图片填充内容
            Image($r('app.media.ic_jd_scroll_01'))
            Image($r('app.media.ic_jd_scroll_02'))
            Image($r('app.media.ic_jd_scroll_03'))
          }
        }
        .scrollBar(BarState.Off) //滑动条消失
        .width('100%')
        .backgroundColor(Color.Orange)
        .onWillScroll(() => {
          //this.sc.currentOffset() 获取当前的偏移量,xOffset获取x轴的,yOffset获取y轴的,如果y轴偏移量大于400,变量值改变使小火箭显隐
          if (this.sc.currentOffset().yOffset > 400) {
            this.showRocket = true
          } else {
            this.showRocket = false
          }
        })

        //用变量控制小火箭显隐
        if (this.showRocket) {
          Image($r('app.media.ic_jd_rocket'))
            .width(40)
            .backgroundColor(Color.White)
            .borderRadius(20)//圆角边框
            .padding(5)// .margin({right:20,bottom:20})
            .offset({ x: -20, y: -20 })//相对本组件左上角的定位,stack设置了右下角,所以是页面的右下角再往左上方偏移20
            .onClick(() => {
              this.sc.scrollEdge(Edge.Top) //滚到上边缘
            })
        }
      }
      .layoutWeight(1) //占剩余的高度,column的‘100%’高度减去tabbar图片的高度

      // 底部 tabbar图片
      Image($r('app.media.ic_jd_tab'))
        .width('100%')

    }.width('100%')
    .height('100%')

  }
}

本系列教程希望你能喜欢,我将会持续更新下去。如果你觉得教程通俗易懂且是你喜欢的风格,请多多点赞、关注!