Selaa lähdekoodia

修复无时间标签歌词不滚动哦

onecold 6 kuukautta sitten
vanhempi
sitoutus
ae842e0c1d
2 muutettua tiedostoa jossa 68 lisäystä ja 70 poistoa
  1. 5 23
      lib/src/main/ets/parse/LyricParser.ts
  2. 63 47
      lib/src/main/ets/view/LyricView2.ets

+ 5 - 23
lib/src/main/ets/parse/LyricParser.ts

@@ -35,7 +35,7 @@ export class LyricParser implements IParser {
 
 
         // 如果没有时间标签,作为纯文本歌词处理
         // 如果没有时间标签,作为纯文本歌词处理
         if (!hasValidTimeTag) {
         if (!hasValidTimeTag) {
-            printD("检测到纯文本歌词(无时间标签),为每行添加默认时间标签");
+            printD("检测到纯文本歌词(无时间标签),不添加时间标签");
             return this.parsePlainTextLyric(src);
             return this.parsePlainTextLyric(src);
         }
         }
 
 
@@ -355,11 +355,6 @@ export class LyricParser implements IParser {
         let by = ""
         let by = ""
         let offset = 0
         let offset = 0
 
 
-        // 为纯文本歌词设置一个起始时间(比如从歌曲开始10秒后)
-        // 这样可以避免一播放就滚走
-        const START_TIME = 10000 // 10秒
-        const LINE_INTERVAL = 5000 // 每行间隔5秒
-
         for (let i = 0; i < src.length; i++) {
         for (let i = 0; i < src.length; i++) {
             let line = src[i].trim()
             let line = src[i].trim()
 
 
@@ -398,26 +393,13 @@ export class LyricParser implements IParser {
                 continue
                 continue
             }
             }
 
 
-            // 为每行设置递增的时间,这样歌词会按顺序显示
-            // 但因为时间间隔较大(5秒),用户可以慢慢阅读
-            let beginTime = START_TIME + (lyricLines.length * LINE_INTERVAL)
-            lyricLines.push(new LyricLine(line, beginTime, -1))
-        }
-
-        // 设置 nextTime
-        for (let i = 0; i < lyricLines.length; i++) {
-            let lyricLine = lyricLines[i]
-            if (i == lyricLines.length - 1) {
-                // 最后一行,设置一个较大的 nextTime 让它持续显示
-                lyricLine.nextTime = lyricLine.beginTime + 60000 // 持续显示1分钟
-            } else {
-                let next = lyricLines[i + 1]
-                lyricLine.nextTime = next.beginTime
-            }
+            // 不添加时间标签,使用 -1 表示纯文本歌词
+            lyricLines.push(new LyricLine(line, -1, -1))
         }
         }
 
 
         printD(`纯文本歌词解析完成,共 ${lyricLines.length} 行歌词`)
         printD(`纯文本歌词解析完成,共 ${lyricLines.length} 行歌词`)
-        let result = new Lyric(artist, title, album, by, offset, lyricLines)
+        // 标记为纯文本歌词
+        let result = new Lyric(artist, title, album, by, offset, lyricLines, true)
         return result
         return result
     }
     }
 }
 }

+ 63 - 47
lib/src/main/ets/view/LyricView2.ets

@@ -83,6 +83,11 @@ export struct LyricView2 {
         }, 300)
         }, 300)
     }
     }
     private onPositionChangedListener = (mediaPosition: number) => {
     private onPositionChangedListener = (mediaPosition: number) => {
+        // 如果是纯文本歌词,不进行位置同步
+        if (this.currentLyric && this.currentLyric.isPlainText) {
+            this.currentMediaPosition = mediaPosition
+            return
+        }
         this.currentMediaPosition = mediaPosition
         this.currentMediaPosition = mediaPosition
         this.onPositionChanged(mediaPosition)
         this.onPositionChanged(mediaPosition)
     }
     }
@@ -232,7 +237,8 @@ export struct LyricView2 {
             const now = Date.now()
             const now = Date.now()
             if (now - this.lastScrollTime  < this.scrollThrottle)  return
             if (now - this.lastScrollTime  < this.scrollThrottle)  return
             this.lastScrollTime  = now
             this.lastScrollTime  = now
-            if (this.isUserTouching) {
+            // 纯文本歌词不支持 seek 操作
+            if (this.isUserTouching && !(this.currentLyric && this.currentLyric.isPlainText)) {
                 //修复The value of "index" is out of range. It must be >= 0 && <= -1. Received value is: -1
                 //修复The value of "index" is out of range. It must be >= 0 && <= -1. Received value is: -1
                 if (center >= 0 && center < this.listAdapter.totalCount()) {
                 if (center >= 0 && center < this.listAdapter.totalCount()) {
                     this.seekIndex = center;
                     this.seekIndex = center;
@@ -258,11 +264,20 @@ export struct LyricView2 {
                     break
                     break
                 case TouchType.Up:
                 case TouchType.Up:
                 case TouchType.Cancel:
                 case TouchType.Cancel:
-                    this.seekUiHideTimeout = setTimeout(() => {
-                        this.seekIndex = -1
-                        this.isUserTouching = false
-                        this.animateToIndex(this.currentIndex)
-                    }, this.autoHideSeekUIDuration)
+                    // 纯文本歌词不需要自动滚动回顶部
+                    if (this.currentLyric && this.currentLyric.isPlainText) {
+                        this.seekUiHideTimeout = setTimeout(() => {
+                            this.seekIndex = -1
+                            this.isUserTouching = false
+                            // 纯文本歌词不调用 animateToIndex,保持在当前位置
+                        }, this.autoHideSeekUIDuration)
+                    } else {
+                        this.seekUiHideTimeout = setTimeout(() => {
+                            this.seekIndex = -1
+                            this.isUserTouching = false
+                            this.animateToIndex(this.currentIndex)
+                        }, this.autoHideSeekUIDuration)
+                    }
             }
             }
         })
         })
     }
     }
@@ -271,62 +286,59 @@ export struct LyricView2 {
     NormalLyricLine(item: LyricLine, index: number) {
     NormalLyricLine(item: LyricLine, index: number) {
         Column(){
         Column(){
             Text(item.text)
             Text(item.text)
-                .fontSize(index == this.currentIndex ?this.textSize*this.controller.getHighlightScale():this.textSize)
+                .fontSize(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?this.textSize*this.controller.getHighlightScale():this.textSize)
                 .textAlign(this.alignMode == 'center' ? TextAlign.Center : TextAlign.Start)
                 .textAlign(this.alignMode == 'center' ? TextAlign.Center : TextAlign.Start)
-                .fontColor(index == this.currentIndex ? this.textHighlightColor : this.textColor)
-                .fontWeight(index == this.currentIndex && this.isHighlightBold ? FontWeight.Bold : this.textWeight)
+                .fontColor(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? this.textHighlightColor : this.textColor)
+                .fontWeight(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) && this.isHighlightBold ? FontWeight.Bold : this.textWeight)
                 .padding(this.isSingleLine?0:{ top:5,bottom:5 })
                 .padding(this.isSingleLine?0:{ top:5,bottom:5 })
                 .visibility(this.isSingleLine?
                 .visibility(this.isSingleLine?
                     (index >= this.currentIndex && index <= this.currentIndex + 1 ? Visibility.Visible : Visibility.None)
                     (index >= this.currentIndex && index <= this.currentIndex + 1 ? Visibility.Visible : Visibility.None)
                     : Visibility.Visible)
                     : Visibility.Visible)
-                .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex ?'95%': '80%')
-                // .animation({
-                //     duration: 150,
-                //     curve: Curve.Linear
-                // })
+                .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?'95%': '80%')
+                .animation({
+                    duration: 150,
+                    curve: Curve.Linear
+                })
                 .blendMode(
                 .blendMode(
-                    index == this.currentIndex ? BlendMode.DST_IN : undefined,
-                    index == this.currentIndex ? BlendApplyType.OFFSCREEN : undefined
+                    index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? BlendMode.DST_IN : undefined,
+                    index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? BlendApplyType.OFFSCREEN : undefined
                 )
                 )
 
 
             // 中文翻译(整行显示)
             // 中文翻译(整行显示)
             if (item.translation)  {
             if (item.translation)  {
 
 
             Text(item.translation)
             Text(item.translation)
-                .fontSize(index == this.currentIndex ?this.textSize*this.controller.getHighlightScale():this.textSize)
+                .fontSize(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?this.textSize*this.controller.getHighlightScale():this.textSize)
                 .fontColor(this.currentMediaPosition >= item.beginTime ?
                 .fontColor(this.currentMediaPosition >= item.beginTime ?
-                    index == this.currentIndex ? this.textHighlightColor : this.textColor : this.textColor)
-                .fontWeight(index == this.currentIndex && this.isHighlightBold ? FontWeight.Bold : this.textWeight)
+                    index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? this.textHighlightColor : this.textColor : this.textColor)
+                .fontWeight(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) && this.isHighlightBold ? FontWeight.Bold : this.textWeight)
                 .padding(this.isSingleLine?{ bottom:2 }:{ bottom:5 })
                 .padding(this.isSingleLine?{ bottom:2 }:{ bottom:5 })
                 .textAlign(this.alignMode == 'center' ? TextAlign.Center : TextAlign.Start)
                 .textAlign(this.alignMode == 'center' ? TextAlign.Center : TextAlign.Start)
                 .visibility(this.isSingleLine?
                 .visibility(this.isSingleLine?
                     (index >= this.currentIndex && index <= this.currentIndex + 1 ? Visibility.Visible : Visibility.None)
                     (index >= this.currentIndex && index <= this.currentIndex + 1 ? Visibility.Visible : Visibility.None)
                     : Visibility.Visible)
                     : Visibility.Visible)
                 .blendMode(
                 .blendMode(
-                    index == this.currentIndex ? BlendMode.DST_IN : undefined,
-                    index == this.currentIndex ? BlendApplyType.OFFSCREEN : undefined
+                    index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? BlendMode.DST_IN : undefined,
+                    index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? BlendApplyType.OFFSCREEN : undefined
                 )
                 )
-                .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex ?'95%': '80%')
-                // .animation({
-                //     duration: 150,
-                //     curve: Curve.Linear
-                // })
+                .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?'95%': '80%')
+                .animation({
+                    duration: 150,
+                    curve: Curve.Linear
+                })
 
 
             }
             }
         }
         }
         // 在 Row 上应用渐变
         // 在 Row 上应用渐变
-        .linearGradient(index == this.currentIndex ? {
+        .linearGradient(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? {
             direction: GradientDirection.Right,
             direction: GradientDirection.Right,
             colors: this.getLyricItemLinearGradient(item, index)
             colors: this.getLyricItemLinearGradient(item, index)
         } : undefined)
         } : undefined)
         .blendMode(
         .blendMode(
-            index == this.currentIndex ? BlendMode.SRC_OVER : undefined,
-            index == this.currentIndex ? BlendApplyType.OFFSCREEN : undefined
+            index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? BlendMode.SRC_OVER : undefined,
+            index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? BlendApplyType.OFFSCREEN : undefined
         )
         )
-        .animation({
-            duration: index == this.currentIndex ?150:0,
-            curve: Curve.Linear
-        })
+
 
 
     }
     }
 
 
@@ -437,10 +449,10 @@ export struct LyricView2 {
 
 
 
 
                     Text(word.word)
                     Text(word.word)
-                        .fontSize(index == this.currentIndex ?this.textSize*this.controller.getHighlightScale():this.textSize)
+                        .fontSize(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?this.textSize*this.controller.getHighlightScale():this.textSize)
                         .fontColor(this.currentMediaPosition >= word.startTime ?
                         .fontColor(this.currentMediaPosition >= word.startTime ?
-                            index == this.currentIndex ? this.textHighlightColor : this.textColor : this.textColor)
-                        .fontWeight(index == this.currentIndex? FontWeight.Bold : this.textWeight)
+                            index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? this.textHighlightColor : this.textColor : this.textColor)
+                        .fontWeight(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText)? FontWeight.Bold : this.textWeight)
                         .margin(isEnglish(word.word) ?{ right:4 }:{})
                         .margin(isEnglish(word.word) ?{ right:4 }:{})
                         .visibility(this.isSingleLine?
                         .visibility(this.isSingleLine?
                             (index >= this.currentIndex && index <= this.currentIndex + 1 ? Visibility.Visible : Visibility.None)
                             (index >= this.currentIndex && index <= this.currentIndex + 1 ? Visibility.Visible : Visibility.None)
@@ -457,16 +469,16 @@ export struct LyricView2 {
                 })
                 })
             }
             }
             .justifyContent(this.alignMode === 'center' ? FlexAlign.Center : FlexAlign.Start)
             .justifyContent(this.alignMode === 'center' ? FlexAlign.Center : FlexAlign.Start)
-            .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex ?'95%': '85%')
+            .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?'95%': '85%')
 
 
             // 中文翻译(整行显示)
             // 中文翻译(整行显示)
             if (item.translation)  {
             if (item.translation)  {
                 Row({ space: 0 }) {
                 Row({ space: 0 }) {
                     Text(item.translation)
                     Text(item.translation)
-                        .fontSize(index == this.currentIndex ?this.textSize*this.controller.getHighlightScale():this.textSize)
+                        .fontSize(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?this.textSize*this.controller.getHighlightScale():this.textSize)
                         .fontColor(this.currentMediaPosition >= item.beginTime ?
                         .fontColor(this.currentMediaPosition >= item.beginTime ?
-                            index == this.currentIndex ? this.textHighlightColor : this.textColor : this.textColor)
-                        .fontWeight(index == this.currentIndex? FontWeight.Bold : this.textWeight)
+                            index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ? this.textHighlightColor : this.textColor : this.textColor)
+                        .fontWeight(index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText)? FontWeight.Bold : this.textWeight)
                         .padding({ bottom:5 })
                         .padding({ bottom:5 })
                         .padding(this.isSingleLine?{ bottom:2 }:{ bottom:5 })
                         .padding(this.isSingleLine?{ bottom:2 }:{ bottom:5 })
                         .visibility(this.isSingleLine?
                         .visibility(this.isSingleLine?
@@ -478,7 +490,7 @@ export struct LyricView2 {
                         })
                         })
                 }
                 }
                 .justifyContent(this.alignMode === 'center' ? FlexAlign.Center : FlexAlign.Start)
                 .justifyContent(this.alignMode === 'center' ? FlexAlign.Center : FlexAlign.Start)
-                .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex ?'95%': '85%')
+                .width(this.alignMode == 'center' ? '100%' :index == this.currentIndex && !(this.currentLyric && this.currentLyric.isPlainText) ?'95%': '85%')
             }
             }
         }
         }
         .height('auto')
         .height('auto')
@@ -531,12 +543,6 @@ export struct LyricView2 {
     JumpProgress(){
     JumpProgress(){
         Row(){
         Row(){
             Row(){
             Row(){
-                // Divider()
-                //     .width(10)
-                //     .strokeWidth(2)
-                //     .color(Color.Transparent)
-                //     .foregroundBlurStyle(BlurStyle.BACKGROUND_REGULAR,
-                //         { colorMode: ThemeColorMode.LIGHT, adaptiveColor: AdaptiveColor.DEFAULT, scale: 1.0 })
 
 
                 Row({space: 10}){
                 Row({space: 10}){
                     Text(this.scrollDurationText)
                     Text(this.scrollDurationText)
@@ -636,6 +642,12 @@ export struct LyricView2 {
 
 
         let size = this.listAdapter.totalCount()
         let size = this.listAdapter.totalCount()
         if (size === 0) return 0 // 空列表保护
         if (size === 0) return 0 // 空列表保护
+
+        // 如果是纯文本歌词,始终返回 0(不滚动)
+        if (this.currentLyric && this.currentLyric.isPlainText) {
+            return 0
+        }
+
         let first = this.listAdapter.getData(0).beginTime
         let first = this.listAdapter.getData(0).beginTime
         if (position < first) {
         if (position < first) {
             return 0
             return 0
@@ -680,6 +692,10 @@ export struct LyricView2 {
             // printW('The lyric lines is empty!')
             // printW('The lyric lines is empty!')
             return
             return
         }
         }
+        // 如果是纯文本歌词,不进行滚动同步
+        if (this.currentLyric && this.currentLyric.isPlainText) {
+            return
+        }
         let index = this.getIndex(mediaPosition)
         let index = this.getIndex(mediaPosition)
         if (index != this.currentIndex) {
         if (index != this.currentIndex) {
             this.animateToIndex(index)
             this.animateToIndex(index)