介紹
本示例介紹了文字寬度過寬時,如何實現文字首尾相接迴圈滾動並顯示在可視區,以及每迴圈滾動一次之後會停滯一段時間後再滾動。
效果圖預覽
使用說明:
1.進入頁面,檢票口文字處,實現文字首尾相接迴圈滾動,且在同一可視區,滾動完成之後,停滯一段時間後繼續滾動。
實現思路
由於ArkUI中的Marquee元件無法實現文字接替並顯示在同一可視區的效果,它只能等文字完全消失在可視區之後,才會再次顯示在可視區, 因此需要以下方案實現。
- 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%')
- 頁面進來執行文字滾動函式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