【HarmonyOS NEXT 】应用开发:ArkTS走马灯Swiper

一、代码示例

1、走马灯效果

2、示例代码

// xxx.ets
class MyDataSource implements IDataSource {
  private list: number[] = []

  constructor(list: number[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): number {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {}

  unregisterDataChangeListener() {}
}

@Entry
@Component
struct SwiperExample {
  private swiperController: SwiperController = new SwiperController()
  private data: MyDataSource = new MyDataSource([])

  aboutToAppear(): void {
    let list: number[] = []
    for (let i = 1; i <= 10; i++) {
      list.push(i);
    }
    this.data = new MyDataSource(list)
  }

  build() {
    Column({ space: 5 }) {
      Swiper(this.swiperController) {
        LazyForEach(this.data, (item: string) => {
          Text(item.toString())
            .width('90%')
            .height(160)
            .backgroundColor(0xAFEEEE)
            .textAlign(TextAlign.Center)
            .fontSize(30)
        }, (item: string) => item)
      }
      // 设置预加载子组件个数, 以当前页面为基准,加载当前显示页面的前后个数
      .cachedCount(2)
      .index(1)
      // 设置子组件是否自动播放。
      .autoPlay(true)
      // 设置使用自动播放时播放的时间间隔。
      .interval(4000)
      // 设置是否开启循环
      .loop(true)
      // 设置禁用组件导航点交互功能。设置为true时表示导航点可交互。
      .indicatorInteractive(true)
      // 设置子组件切换的动画时长。
      .duration(1000)
      // 设置子组件与子组件之间间隙。不支持设置百分比。
      .itemSpace(0)
      // 设置圆点导航点样式
      .indicator(
        new DotIndicator()
          .itemWidth(15)
          .itemHeight(15)
          .selectedItemWidth(15)
          .selectedItemHeight(15)
          .color(Color.Gray)
          .selectedColor(Color.Blue))
      // 设置导航点箭头样式
      .displayArrow({
        showBackground: true,
        isSidebarMiddle: true,
        backgroundSize: 24,
        backgroundColor: Color.White,
        arrowSize: 18,
        arrowColor: Color.Blue
      }, false)
      // 设置Swiper的动画曲线, 默认为弹簧插值曲线
      .curve(Curve.Linear)
      // 当前显示的子组件索引变化时触发该事件,返回值为当前显示的子组件的索引值。
      .onChange((index: number) => {
        console.info(index.toString())
      })
      // 在页面跟手滑动过程中,逐帧触发该回调。多列Swiper时,index为最左侧组件的索引。
      .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
        console.info("index: " + index)
        console.info("current offset: " + extraInfo.currentOffset)
      })
      // 切换动画开始时触发该回调。参数为动画开始前的index值(不是最终结束动画的index值),多列Swiper时,index为最左侧组件的索引。
      .onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {
        console.info("index: " + index)
        console.info("targetIndex: " + targetIndex)
        console.info("current offset: " + extraInfo.currentOffset)
        console.info("target offset: " + extraInfo.targetOffset)
        console.info("velocity: " + extraInfo.velocity)
      })
      // 切换动画结束时触发该回调。
      .onAnimationEnd((index: number, extraInfo: SwiperAnimationEvent) => {
        console.info("index: " + index)
        console.info("current offset: " + extraInfo.currentOffset)
      })

      Row({ space: 12 }) {
        Button('showNext')
          .onClick(() => {
            // 点击展示下一个
            this.swiperController.showNext()
          })
        Button('showPrevious')
          .onClick(() => {
            // 点击展示上一个
            this.swiperController.showPrevious()
          })
      }.margin(5)
    }.width('100%')
    .margin({ top: 5 })
  }
}
二、参数含义

1、cachedCount(number)

设置预加载子组件个数, 以当前页面为基准,加载当前显示页面的前后个数
2、index(1)
设置当前在容器中显示的子组件的索引值。
3、autoPlay(true)
设置子组件是否自动播放。
4、interval(4000)
设置使用自动播放时播放的时间间隔。
5、loop(true)
设置是否开启循环
6、indicatorInteractive(true)
设置禁用组件导航点交互功能。设置为true时表示导航点可交互。
7、duration(1000)
设置子组件切换的动画时长。
8、itemSpace(0)
设置子组件与子组件之间间隙。不支持设置百分比。
9、indicator()
设置圆点导航点样式
10、displayArrow({
  showBackground: true,
  isSidebarMiddle: true,
  backgroundSize: 24,
  backgroundColor: ColorWhite,
  arrowSize: 18,
  arrowColor: ColorBlue
}, false)
设置导航点箭头样式
11、curve(CurveLinear)
设置Swiper的动画曲线, 默认为弹簧插值曲线
12、onChange((index: number) => {})
当前显示的子组件索引变化时触发该事件,返回值为当前显示的子组件的索引值。
13、onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {})

在页面跟手滑动过程中,逐帧触发该回调。多列Swiper时,index为最左侧组件的索引。
14、onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {})

切换动画开始时触发该回调。参数为动画开始前的index值(不是最终结束动画的index值),多列Swiper时,index为最左侧组件的索引。
15、onAnimationEnd((index: number, extraInfo: SwiperAnimationEvent) => {})

切换动画结束时触发该回调。

三、自定义切换动画

 本示例通过customContentTransition接口实现了自定义Swiper页面切换动画。

// xxx.ets
@Entry
@Component
struct SwiperCustomAnimationExample {
  private DISPLAY_COUNT: number = 2
  private MIN_SCALE: number = 0.75

  @State backgroundColors: Color[] = [Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.Gray, Color.Orange]
  @State opacityList: number[] = []
  @State scaleList: number[] = []
  @State translateList: number[] = []
  @State zIndexList: number[] = []

  aboutToAppear(): void {
    for (let i = 0; i < this.backgroundColors.length; i++) {
      this.opacityList.push(1.0)
      this.scaleList.push(1.0)
      this.translateList.push(0.0)
      this.zIndexList.push(0)
    }
  }

  build() {
    Column() {
      Swiper() {
        ForEach(this.backgroundColors, (backgroundColor: Color, index: number) => {
          Text(index.toString()).width('100%').height('100%').fontSize(50).textAlign(TextAlign.Center)
            .backgroundColor(backgroundColor)
            // 自定义动画变化透明度、缩放页面、抵消系统默认位移、渲染层级等
            .opacity(this.opacityList[index])
            .scale({ x: this.scaleList[index], y: this.scaleList[index] })
            .translate({ x: this.translateList[index] })
            .zIndex(this.zIndexList[index])
        })
      }
      .height(300)
      .indicator(false)
      .displayCount(this.DISPLAY_COUNT, true)
      .customContentTransition({
        // 页面移除视窗时超时1000ms下渲染树
        timeout: 1000,
        // 对视窗内所有页面逐帧回调transition,在回调中修改opacity、scale、translate、zIndex等属性值,实现自定义动画
        transition: (proxy: SwiperContentTransitionProxy) => {
          if (proxy.position <= proxy.index % this.DISPLAY_COUNT || proxy.position >= this.DISPLAY_COUNT + proxy.index % this.DISPLAY_COUNT) {
            // 同组页面往左滑或往右完全滑出视窗外时,重置属性值
            this.opacityList[proxy.index] = 1.0
            this.scaleList[proxy.index] = 1.0
            this.translateList[proxy.index] = 0.0
            this.zIndexList[proxy.index] = 0
          } else {
            // 同组页面往右滑且未滑出视窗外时,对同组中左右两个页面,逐帧根据position修改属性值,实现两个页面往Swiper中间靠拢并透明缩放的自定义切换动画
            if (proxy.index % this.DISPLAY_COUNT === 0) {
              this.opacityList[proxy.index] = 1 - proxy.position / this.DISPLAY_COUNT
              this.scaleList[proxy.index] = this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - proxy.position / this.DISPLAY_COUNT)
              this.translateList[proxy.index] = - proxy.position * proxy.mainAxisLength + (1 - this.scaleList[proxy.index]) * proxy.mainAxisLength / 2.0
            } else {
              this.opacityList[proxy.index] = 1 - (proxy.position - 1) / this.DISPLAY_COUNT
              this.scaleList[proxy.index] = this.MIN_SCALE + (1 - this.MIN_SCALE) * (1 - (proxy.position - 1) / this.DISPLAY_COUNT)
              this.translateList[proxy.index] = - (proxy.position - 1) * proxy.mainAxisLength - (1 - this.scaleList[proxy.index]) * proxy.mainAxisLength / 2.0
            }
            this.zIndexList[proxy.index] = -1
          }
        }
      })
      .onContentDidScroll((selectedIndex: number, index: number, position: number, mainAxisLength: number) => {
        // 监听Swiper页面滑动事件,在该回调中可以实现自定义导航点切换动画等
        console.info("onContentDidScroll selectedIndex: " + selectedIndex + ", index: " + index + ", position: " + position + ", mainAxisLength: " + mainAxisLength)
      })
    }.width('100%')
  }
}

【1】参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值