HarmonyOS NEXT應用開發之深色跑馬燈案例

生活就是这么怪發表於2024-04-19

介紹

本示例介紹了文字寬度過寬時,如何實現文字首尾相接迴圈滾動並顯示在可視區,以及每迴圈滾動一次之後會停滯一段時間後再滾動。

效果圖預覽

image

使用說明

1.進入頁面,檢票口文字處,實現文字首尾相接迴圈滾動,且在同一可視區,滾動完成之後,停滯一段時間後繼續滾動。

實現思路

由於ArkUI中的Marquee元件無法實現文字接替並顯示在同一可視區的效果,它只能等文字完全消失在可視區之後,才會再次顯示在可視區, 因此需要以下方案實現。

  1. Text元件外層包裹一層Scroll元件,Scroll元件設定一定的百分比寬度值,並獲取當前文字內容寬度和Scroll元件寬度,文字寬度大於 Scroll元件寬度時,透過新增判斷顯示同樣的文字,在偏移過程中可實現文字接替並顯示在同一顯示區的效果。原始碼參考Marquee.ets
    // TODO:知識點:使用Scroll元件和文字內容元件結合來判斷文字寬度過寬時執行文字滾動,否則不執行
    Scroll() {
      Row() {
        Text(this.tripDataItem.ticketEntrance)
          .onAreaChange((oldValue, newValue) => {
            logger.info(`TextArea oldValue:${JSON.stringify(oldValue)},newValue:${JSON.stringify(newValue)}`);
            // 獲取當前文字內容寬度
            this.ticketCheckTextWidth = Number(newValue.width);
          })
        // TODO:知識點:文字寬度大於Scroll元件寬度時顯示。在偏移過程中可實現文字接替並顯示在同一顯示區的效果
        if (this.ticketCheckTextWidth >= this.ticketCheckScrollWidth) {
          Blank()
            .width(50)
          Text(this.tripDataItem.ticketEntrance)
        }
      }.offset({ x: this.ticketCheckTextOffset })
    }
    .width('50%')
    .align(Alignment.Start)
    .enableScrollInteraction(false)
    .flexGrow(1)
    .scrollable(ScrollDirection.Horizontal)
    .scrollBar(BarState.Off)
    .onAreaChange((oldValue, newValue) => {
      logger.info(`scrollArea oldValue:${JSON.stringify(oldValue)},newValue:${JSON.stringify(newValue)}`);
      // 獲取當前Scroll元件寬度
      this.ticketCheckScrollWidth = Number(newValue.width);
    })
   }
   .width('46%')
  1. 頁面進來執行文字滾動函式scrollAnimation(),在指定的時間內完成文字的偏移,當迴圈一次之後,透過定時器setTimeout 來實現停滯操作。原始碼參考Marquee.ets
   // 文字滾動函式
  scrollAnimation() {
    // 文字寬度小於Scroll元件寬度,不執行滾動操作
    if (this.ticketCheckTextWidth < this.ticketCheckScrollWidth) {
      return;
    }
    /**
     * 文字向左偏移動畫
     *
     * @param duration:動畫總時長
     * @param curve:動畫曲線
     * @param delay:延遲時間
     * @param onFinish:完成回撥函式
     * 效能:播放動畫時,系統需要在一個重新整理週期內完成動畫變化曲線的計算,完成元件佈局繪製等操作。建議使用系統提供的動畫介面,
     * 只需設定曲線型別、終點位置、時長等資訊,就能夠滿足常用的動畫功能,減少UI主執行緒的負載。
     * 參考資料:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-attribute-animation-apis-0000001820879805
     */
    animateTo({
      duration: Constants.ANIMATION_DURATION,
      curve: Curve.Linear,
      delay: this.delay,
      onFinish: () => {
        // TODO:知識點:動畫完成時,新增定時器,1s之後重新執行動畫函式,達到停滯操作。
        setTimeout(() => {
          // 初始化文字偏移量
          this.ticketCheckTextOffset = 0;
          this.scrollAnimation();
        }, Constants.DELAY_TIME)
      }
    }, () => {
      // 文字偏離量
      this.ticketCheckTextOffset = -(this.ticketCheckTextWidth + Constants.BLANK_SPACE)
    })
  }

高效能知識點

本示例使用了LazyForEach 進行資料懶載入,動態新增行程資訊以及顯示動畫animateTo實現文字偏移。

工程結構&模組型別

marquee                                         // har型別
|---model
|   |---Constants.ets                           // 資料模型層-常量
|   |---DataSource.ets                          // 模型層-懶載入資料來源
|   |---DataType.ets                            // 資料模型層-資料型別
|   |---MockData.ets                            // 資料模型層-模擬資料
|---view
|   |---Marquee.ets                             // 檢視層-應用主頁面

模組依賴

本例項依賴common模組來實現日誌的列印、資源 的呼叫。

參考資料

顯示動畫animateTo

資料懶載入LazyForEach

相關文章