概要
我有一个字符串[tab] [ch]C[/ch] [ch]Am[/ch] \n 我听说有一个秘密和弦[/tab]
当TextView足够大,不需要换行时,它应该(并且确实)看起来像这样:
C Am
I heard there was a secret chord
当行(或几行)过长以至于无法适应TextView时,我希望它能像这样自动换行:
C
I heard there was a
Am
secret chord
现在它是这样包装的(就像你期望的那样,如果它只是文本)
C
Am
I heard there was a
secret chord
约束条件:
- 我使用等宽字体以保持对齐
- 和弦(
C
、F
、Am
、G
)是可点击的,因此如果您制作自定义的 TextView 实现,它仍然必须能够处理ClickableSpans
或者保持它们可点击 - Kotlin 或 Java(或 XML)都可以
如果有帮助的话,这是我的一个开源项目,因此源代码可在 Github 上找到。这是 片段源码(查找 fun processTabContent(text: CharSequence)
-- 那是我目前处理文本的地方)。这是 布局 xml。
输入格式
我的数据以单个字符串的形式存储(这无法更改 - 我从API中获取它)。以下是上述选项卡的格式:
[Intro]\n[tab][ch]C[/ch] [ch]Am[/ch] [ch]C[/ch] [ch]Am[/ch][/tab]\n[Verse 1][tab] [ch]C[ch] [ch]Am[/ch] I heard there was a secret chord [/tab][tab] [ch]C[/ch] [ch]Am[/ch]\nThat David played, and it pleased the Lord[/tab][tab] [ch]C[/ch] [ch]F[/ch] [ch]G[/ch]\n But you don't really care for music, do you?[/tab]
请注意,和弦(一个吉他手会弹奏的音符,例如
C
或F
)被包含在[ch]
标签中。我目前有一个可以找到它们、删除[ch]
标签并将每个和弦都包装在ClickableSpan
中的代码。单击时,我的应用程序将显示另一个片段,其中包含有关如何在吉他上演奏该和弦的说明。这只有重要的是,对这个问题的答案必须仍然允许这些和弦像这样被点击。
我现在正在做的事情(不起作用的部分)
你现在可能已经注意到了,我们需要集中关注[tab]
标签。现在,我正在浏览字符串,用换行符替换[tab]
并删除所有[/tab]
的实例。如果我的TextView
文本大小足够小,整行都可以适合设备屏幕,那么这就没问题了。但是,当单词折行开始时,我就出现了问题。
这个:
C Am
I heard there was a secret chord
应该包装成这样:
C
I heard there was a
Am
secret chord
但是实际上会像这样包装:
C
Am
I heard there was a
secret chord
C
、Am
、F
和G
告诉吉他手该演奏哪个音符。吉他手可以根据它所在的单词来确定演奏该音符的时间。对于数据结构来说,整个选项卡都在一个巨大的字符串中,包括和弦和歌词。但是,它使用[ch]
/[/ch]
标签包装和弦,并使用[tab]
/[/tab]
标签包装应该一起包装的几行(一行和弦和一行歌词)。希望这有所帮助。 - CullubTextView
中,该TextView
位于ConstraintLayout
内。如果您需要查看 XML,请单击此处(https://github.com/cullub/Tabs-Lite/blob/master/app/src/main/res/layout/fragment_tab_detail.xml)。片段代码(目前非常庞大)在此处(https://github.com/cullub/Tabs-Lite/blob/master/app/src/main/java/com/gbros/tabslite/TabDetailFragment.kt)。Ctrl-F 查找fun processTabContent
- 这是我目前进行处理的地方。 - Cullub