需求

开发时内容超出显示范围,遥控器获焦后想要具备自动滚动功能,并能够实现无缝循环播放的效果,使首尾项连接自然,不出现空白或卡顿现象。

实现方法

List组件是可滚动的容器组件列表包含一系列相同宽度的列表项。适合连续、多行呈现同类数据,例如图片或自定义组件。

setInterval定时器可以重复调用一个函数,在每次调用之间可以设置固定的时间延迟,配合ListScroller的scrollTo函数,可以控制List的滚动。

在获焦后执行滚动操作。

核心实现

通过setInterval定时器循环执行this.scroller.scrollTo达到自动滚动的效果。数据源要有两边实现首尾相连的效果。

//滚动控制
  startAutoRoll() {
    if (this.isForcus) {
      if (this.iconData.length > 3) {

        this.IntervalNum = setInterval(() => {
          this.rollOffset += 1
          if (this.isEnd) {
            this.rollOffset = 1
          }
          this.scroller.scrollTo({ xOffset: this.rollOffset, yOffset: 0, animation: false })

        }, 10)
      }
    }
  }

完整示例

@Entry
@ComponentV2
struct ListScroll {
  scroller: Scroller = new Scroller()
  @Param index: number = 0
  @Param iconData: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @Local listWidth: number = 0
  @Local isEnd: boolean = false
  @Local isForcus: boolean = false
  private rollOffset: number = 0
  private IntervalNum: number = 0

  //滚动控制
  startAutoRoll() {
    if (this.isForcus) {
      if (this.iconData.length > 3) {

        this.IntervalNum = setInterval(() => {
          this.rollOffset += 1
          if (this.isEnd) {
            this.rollOffset = 1
          }
          this.scroller.scrollTo({ xOffset: this.rollOffset, yOffset: 0, animation: false })

        }, 10)
      }
    }
  }

  aboutToAppear() {
    this.getUIContext().getFocusController().activate(true, false)
    //两层
    for (let index = 0; index < 10; index++) {
      this.iconData.push(index)
    }
  }

  aboutToDisappear(): void {
    clearInterval(this.IntervalNum)
  }

  getText(num: number) {
    let res: string = ''
    for (let index = 0; index <= num; index++) {
      res += num.toString()
    }
    return res
  }

  build() {

    Column() {
      Text('获焦后无限滚动')
        .fontColor("#ff0637a2")
        .margin(20)
        .fontSize(40)
        .id('text')
        .fontWeight(FontWeight.Medium)
        .focusable(true)
        .onClick(() => {
        })

      Row() {
        List({ scroller: this.scroller }) {
          ForEach(this.iconData, (url: number, index) => {
            ListItem() {
              Text('获焦后无限滚动 ' + this.getText(url))
                .height(100)
                .maxLines(1)
                .margin(5)
                .padding(5)
                .borderWidth(1)
            }
          })
        }
        //也可以默认滚动
        // .onAppear(()=>{
        //   this.startAutoRoll()
        // })
        .fadingEdge(true)
        .scrollBar(BarState.Off)
        .height(120)
        .listDirection(Axis.Horizontal)
        .width('100%')
        .onScrollIndex((start) => {
          if (start == this.iconData.length / 2) {
            this.isEnd = true
          } else {
            this.isEnd = false
          }
        })
      }
      .height(120)
      .width('100%')
      .onClick(() => {
      })
      .onFocus(() => {
        this.isForcus = true
        this.startAutoRoll()
      })
      .onBlur(() => {
        this.isForcus = false
        this.rollOffset = 0
        this.scroller.scrollTo({ xOffset: this.rollOffset, yOffset: 0, animation: false })
        clearInterval(this.IntervalNum)
      })
      .onHover((e) => {
        this.isForcus = e
        if (this.isForcus) {
          this.startAutoRoll()
        }else {
          this.rollOffset = 0
          this.scroller.scrollTo({ xOffset: this.rollOffset, yOffset: 0, animation: false })
          clearInterval(this.IntervalNum)
        }
      })

    }
    .padding(20)
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
  }
}

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐