如何制作一个可组合项来显示歌曲歌词,并在歌词上方显示和弦?

问题描述 投票:0回答:1

我有这个 json 对象:

{
    "number": "060",
    "audio": false,
    "chord": false,
    "code": "each_step_of_the_way",
    "chordUrl": null,
    "name": "EACH STEP OF THE WAY",
    "description": null,
    "mainChord": "F",
    "audioUrl": "/files/en/only_believe/audios/060.mp3",
    "songBook": {
        "id": 1,
        "name": "ONLY BELIEVE",
        "code": "only_believe",
        "userId": 3,
        "hidden": false,
        "addedBy": "SYSTEM",
        "description": null,
        "languageId": 2,
        "isDraft": false,
        "version": "v0.0.1",
        "createdAt": "2023-10-15T23:22:12.485+00:00",
        "updatedAt": "2023-10-15T23:22:12.485+00:00",
        "language": {
            "id": 2,
            "name": "English",
            "code": "en",
            "createdAt": null,
            "updatedAt": null
        }
    },
    "author": null,
    "language": {
        "id": 2,
        "name": "English",
        "code": "en",
        "createdAt": null,
        "updatedAt": null
    },
    "verses": [
        {
            "id": 17371,
            "verseOrder": 1,
            "orderToShow": 1,
            "isRefrain": false,
            "line": "I'm [G]following Jesus, [C]One step at [D]a time;",
            "songId": 4008,
            "createdAt": "2023-10-15T23:22:12.594+00:00",
            "updatedAt": "2023-10-15T23:22:12.594+00:00"
        },
        {
            "id": 17372,
            "verseOrder": 2,
            "orderToShow": 2,
            "isRefrain": false,
            "line": "[G]The pathway is [C]narrow, But He leads [D]me on;",
            "songId": 4008,
            "createdAt": "2023-10-15T23:22:12.595+00:00",
            "updatedAt": "2023-10-15T23:22:12.595+00:00"
        }
    ]
}

使用 jetpack compose 我想解析它并得到这个结果:

 EACH STEP OF THE WAY

           G             C       D
1. I'm following Jesus, One step at a time;

    G               C                  D
2. The pathway is narrow, But He leads me on;

无论屏幕尺寸如何。

我尝试使用此代码,但它不起作用:

fun getSongs(): MutableList<Line> {
    val verses = listOf(
        "Я[A] так слаб, но силен Т[Bm]ы,$ У[E7]держать меня вда[A]л[E7]и$",
        "О[A]т всег[A7]о, что мне вред[D]ит[Bm],$ О[D#o],",
        " позво[A/e]ль лишь с Тобо[E7]ю идт[A]и[D][A][E7].$",
    )
    val list: MutableList<MutableList<Line>> = mutableListOf()

    val chordRegex = """\[(\w+)]""".toRegex()
    val line: MutableList<Line> = mutableListOf()

    verses.forEach { verse ->
        val chords = mutableListOf<Word>()
        val words = mutableListOf<Word>()

        verse.split(" ").forEach { word ->
            val matchResult = chordRegex.find(word)
            if (matchResult != null) {
                val extractedChord = matchResult.groupValues[1]
                chords.add(Word(text = extractedChord, isChord = true))
                words.add(
                    Word(
                        text = word.replace("[$extractedChord]", ""),
                        isChord = false,
                    )
                )
            } else {
                chords.add(Word(text = "", isChord = false))
                words.add(Word(text = word, isChord = false))
            }
        }
        line.add(Line(row = chords, isChord = true))
        line.add(Line(row = words, isChord = false))
    }

    return line
}
android kotlin android-jetpack-compose android-jetpack-compose-material3
1个回答
0
投票

你的解析逻辑对我来说看起来很好。现在要在文本上方绘制和弦,您可以在

Text
内使用
Column
可组合项,如下所示:

@Composable
fun TextChordsComposable() {
    val songString = remember { "I'm foll[D]owing [G]Jesus, One st[C]ep at a time[D]" }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .wrapContentHeight()
            .padding(16.dp),
        verticalAlignment = Alignment.Bottom
    ) {
        songString.split(" ").forEach { word: String ->
            val regex = """\[(\w+)]""".toRegex()
            val matchResult = regex.find(word)

            if (matchResult != null) {
                val chord = matchResult.groupValues[1]
                val rawWord = word.replace(regex, "")
                Text(
                    text = "$chord\n$rawWord "
                )
            } else {
                Text(
                    text = "$word "
                )
            }
        }
    }
}

输出如下所示:

screenshot

如果您想根据单词中

[]
的位置来定位和弦,则需要更高级的解析逻辑来检查
[]
是否位于单词的开头、中间或结尾。

© www.soinside.com 2019 - 2024. All rights reserved.