kotlinforandroid
06/19/2022, 11:27 AMInlineTextContent
. I am trying to add readings annotations to existing text. However, if I simply add the exact same text using a placeholder, the text gets added written vertically for some reason. I think the reason is that the placeholder width isn't exactly the same as the width the original text would have needed. But the way I did it I do not see the issue. (thread)import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.*
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.em
data class TextData(
val text: String,
val reading: String? = null,
)
@Composable
fun TextWithReading(
textData: List<TextData>,
) {
val (text, inlineContent) = remember(textData) {
calculateAnnotatedString(textData)
}
Text(text = text, inlineContent = inlineContent)
}
private fun calculateAnnotatedString(textData: List<TextData>): Pair<AnnotatedString, Map<String, InlineTextContent>> {
val inlineContent = mutableMapOf<String, InlineTextContent>()
return buildAnnotatedString {
for (elem in textData) {
val text = elem.text
val reading = elem.reading
// If there is not reading available, simply add the text and move to the next element.
if (reading == null) {
append(text)
continue
}
appendInlineContent(text, text)
inlineContent[text] = InlineTextContent(
placeholder = Placeholder(
width = text.length.em,
height = 2.em,
placeholderVerticalAlign = PlaceholderVerticalAlign.Bottom,
),
children = {
val readingFontSize = LocalTextStyle.current.fontSize / 2
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom,
) {
Text(
text = reading,
style = TextStyle.Default.copy(fontSize = readingFontSize)
)
Text(text = text)
}
}
)
}
} to inlineContent
}
@Preview
@Composable
internal fun PreviewTextWithReading() {
val textData = listOf(
TextData(text = "このルールを"),
TextData(text = "守", reading = "まも"),
TextData(text = "るらない"),
TextData(text = "人", reading = "ひと"),
TextData(text = "は"),
TextData(text = "旅行", reading = "りょこう"),
TextData(text = "ができなくなることもあります。"),
)
MaterialTheme {
TextWithReading(textData = textData)
}
}
旅行
is written as marked with the red box even though there is still space left on the right of the first character.Zach Klippenstein (he/him) [MOD]
06/22/2022, 8:06 PM