Thanks to visit codestin.com
Credit goes to gitcode.com

lyric-view-cj:基于 Cangjie 的自定义歌词组件项目

音乐播放器自动滚动歌词组UI件

分支7Tags3

lyric-view-cj

介绍

lyric-view-cj 是一个可关联音乐播放器的自定义歌词组件。

特性

  • 从文件解析双语歌词
  • 从文本解析双语歌词
  • 设置拖动歌词时选中歌词的字体颜色
  • 设置拖动歌词时左侧时间字体颜色
  • 设置歌词为空时屏幕中央显示的文字,如“暂无歌词”
  • 支持自定义样式

源码目录

├─ AppScope
├─ doc                   # API文档和使用手册存放目录                   
├─ entry                 # 示例代码文件夹
├─ hvigor                # 构建工具目录              
├─ lyricview             # lyricview 库源目录                  
│  └─ src
│      └─ main
│          ├─ cangjie    # lyricview 源码     
│          └─ resources  # 资源文件
└─ README.md             # lyric-view-cj 介绍及使用说明

接口说明

主要类和函数接口说明详见 API

使用说明

  1. 通过 module 引入
    1. 克隆下载项目
    2. 将 lyricview 模块拷贝到应用项目下
    3. 修改 entry 下的 cjpm.toml 文件,在此文件中添加 lyricview 依赖,如下:
      [dependencies]
        [dependencies.lyricview]
          path = "../lyricview"
      
    4. 在项目中引用 lyricview 项目
      import lyricview.*
      
  2. 把 lyricview 作为三方库依赖引入
    1. 目标工程把 lyricview 依赖库作为 git submodule 引入
      > cd $工程根目录
      > mkdir third-party
      > cd third-party
      > git submodule add "https://gitcode.com/Cangjie-TPC/lyric-view-cj"
      
    2. 修改 entry 下的 cjpm.toml 文件,在此文件中添加 lyricview 依赖,如下:
      [dependencies]
        [dependencies.lyricview]
          path = "../lyricview"
      
    3. 在项目中使用 lyricview 组件
      import lyricview.*
      

功能示例

import ohos.state_macro_manage.*
import ohos.component.*
import std.collection.ArrayList
import ohos.base.*
import ohos.component.*
import ohos.state_manage.*
import ohos.hilog.Hilog

import lyricview.bean.*
import lyricview.extensions.*
import lyricview.parse.*
import lyricview.view.*
import std.sync.*
import std.math.*

@Entry
@Component
class LyricViewTestCase {
    @State
    var mediaPosition: Int64 = 0
    var lyric: Option<Lyric> = None
    @State
    var lyricController: LyricController = LyricController()
    var testIndex = 0
    var testTimer = -1
    var emptyDuration: Int64 = 60 * 1000
    var parser: LyricParser = LyricParser()
    @State
    var title: String = ""
    @State
    var isV2: Bool = true
    var i = 0
    var j = 0
    private var timerInstance: ?Timer = None

    protected func aboutToAppear():Unit {
        this.lyricController
            .setTextSize(18.0)
            .setCacheSize(4)
            .setTextColor(Color(0x7cffffff))
            .setHighlightColor(Color(0xffffffff))
            .setLineSpace(18.0)
            .setHighlightScale(1.3)
            .setHighlightBold(true)
            .setHighlightBold(false)
            .setEmptyHint("当前没有歌词")
            .setAlignMode(AlignMode.Center)
    }

    public func cbFn(mediaPositionT: Int64): Unit {
        this.mediaPosition = mediaPositionT
    }

    func build() {
        Column() {
            Text(this.title).margin(16).fontColor(Color(0xffffff)).fontSize(24).fontColor(Color(0x80ffffff))
            Row() {
                LyricView(
                    controller: this.lyricController,
                    enableSeek: true,
                    seekUIColor: Color(0xffd4d4d4),
                    seekLineColor: Color(0xffffffff),
                    seekUIStyle: "listItem",
                    onSeekAction: {
                        position =>
                        this.mediaPosition = position
                        return true
                    }
                )
            }.width(100.percent).layoutWeight(1)

            Column() {
                Row() {
                    Text('centerMode').fontColor(Color(0xffffff)).fontSize(16).padding(4)
                    Toggle(ToggleType.SwitchType, isOn: true).onChange(
                        {
                            isOn => if (isOn) {
                                this.lyricController.setAlignMode(AlignMode.Center)
                            } else {
                                this.lyricController.setAlignMode(AlignMode.Left)
                            }
                        })
                }

                Row() {
                    Button('play')
                        .fontSize(16)
                        .margin(left: 16)
                        .onClick(
                            {
                                =>
                                this.testIndex++
                                this.lyric = this.parser.parse(testLrcArray)
                                if (let Some(currentLyric) <- this.lyric) {
                                    this.title = currentLyric.getTitle()
                                    this.lyricController.setLyric(currentLyric)
                                }
                                if (let Some(timerInstance) <- this.timerInstance) {
                                    timerInstance.cancel()
                                }
                                this.mediaPosition = 0
                                this.timerInstance = this.lyricController.lyricsScrolling(cbFn)
                            }
                        )

                    Button('color')
                        .fontSize(16)
                        .margin(left: 16)
                        .onClick(
                            {
                                =>
                                this.i++
                                if (this.i % 2 == 0) {
                                    this
                                        .lyricController
                                        .setTextColor(Color(0x80ffffff))
                                        .setHighlightColor(Color(0xffffffff))
                                } else {
                                    this
                                        .lyricController
                                        .setTextColor(Color(0x80e3d052))
                                        .setHighlightColor(Color(0xe3d052))
                                }
                            }
                        )

                    Button('size')
                        .fontSize(16)
                        .margin(left: 16)
                        .onClick(
                            {
                                =>
                                this.j++
                                if (this.j % 2 == 0) {
                                    this.lyricController.setTextSize(12.0).setLineSpace(12.0)
                                } else {
                                    this.lyricController.setTextSize(18.0).setLineSpace(18.0)
                                }
                            }
                        )

                    Button('clear')
                        .fontSize(16)
                        .margin(left: 16)
                        .onClick(
                            {
                                =>
                                let lyric: Option<Lyric> = None
                                this.lyricController.setLyric(lyric)
                            }
                        )
                }.width(100.percent).justifyContent(FlexAlign.SpaceBetween).margin(top: 16)
            }.width(100.percent).justifyContent(FlexAlign.Center).margin(top: 36)

            Slider(
                style: SliderStyle.InSet,
                max: if (let Some(lyric) <- this.lyric) {
                    Float64(lyric.getLyricList()[lyric.getLyricList().size - 1].getBeginTime())
                } else {
                    Float64(this.emptyDuration)
                },
                value: Float64(this.mediaPosition)
            )
                .blockColor(Color(0xfffafafa))
                .trackColor(Color(0xffffff))
                .width(100.percent)
                .onChange(
                    {
                        value: Float64, mode: SliderChangeMode => if (getSliderChangeMode(mode) || getMode(mode) == 3) {
                            this.mediaPosition = Int64(value)
                            this.lyricController.updatePosition(this.mediaPosition)
                        }
                    })
            Text(Int64(round(Float64(this.mediaPosition / 1000))).toString() + "s")
                .fontColor(Color(0xffffff))
                .fontSize(18)
                .margin(top: 16)
        }.linearGradient(
                angle: 360.0,
                colors: [(Color(0xff2e3030), 0.0), (Color(0x662e3030), 1.0)]
            )
            .padding(16)
            .width(100.percent)
            .height(100.percent)
            .justifyContent(FlexAlign.Center)
    }

    public func getSliderChangeMode(that: SliderChangeMode): Bool {
        match (that) {
            case SliderChangeMode.End => true
            case _ => false
        }
    }

    public func getMode(that: SliderChangeMode): Int64 {
        match (that) {
            case SliderChangeMode.Begin => 1
            case SliderChangeMode.Moving => 2
            case SliderChangeMode.End => 3
            case _ => 4
        }
    }
}

约束与限制

已在以下版本中验证通过:

DevEco Studio 5.1.1 Release(5.1.1.851) 需使用支持19及以上版本的SdkVersion

开源协议

本项目基于 Apache License 许可,欢迎您享受并参与开源。

参与贡献

欢迎提交 PR、Issue 或通过任何形式参与贡献。

项目介绍

音乐播放器自动滚动歌词组UI件

定制我的领域