🔖

JetpackCompose 一つの文字列に色んな装飾+複数のクリックアクションを付与する

2023/07/06に公開

長い一行の文字列を色んな装飾した上で色んなアクション生やしたくなることありますよね???

私はあったので調査してみました

サンプルコード&見た目

@Composable
fun MultiClickableText() {
    val text = "hogehogeとhugahugaでageageしてpogepogeなのです"
    val hogeStart = text.indexOf("hogehoge")
    val hogeEnd = hogeStart + "hogehoge".length
    val hugaStart = text.indexOf("hugahuga")
    val hugaEnd = hugaStart + "hugahuga".length
    val ageStart = text.indexOf("ageage")
    val ageEnd = ageStart + "ageage".length
    val pogeStart = text.indexOf("pogepoge")
    val pogeEnd = pogeStart + "pogepoge".length

    val annotatedText = buildAnnotatedString {
        append(text)
        addStyle(
            SpanStyle(color = Color.Red),
            hogeStart,
            hogeEnd
        )
        addStringAnnotation(
            "hoge",
            "hoge",
            hogeStart,
            hogeEnd
        )
        addStyle(
            SpanStyle(color = Color.Blue),
            hugaStart,
            hugaEnd
        )
        addStringAnnotation(
            "huga",
            "huga",
            hugaStart,
            hugaEnd
        )
        addStyle(
            SpanStyle(color = Color.Green),
            ageStart,
            ageEnd
        )
        addStringAnnotation(
            "age",
            "age",
            ageStart,
            ageEnd
        )
        addStyle(
            SpanStyle(color = Color.Yellow),
            pogeStart,
            pogeEnd
        )
        addStringAnnotation(
            "poge",
            "poge",
            pogeStart,
            pogeEnd
        )
    }
    ClickableText(
        text = annotatedText,
        modifier = Modifier.background(Color.White)
    ) { offset ->
        when(offset) {
            in hogeStart.. hogeEnd -> hogeAction
            in hugaStart.. hugaEnd -> hugaAction
            in ageStart.. ageEnd -> ageAction
            in pogeStart.. pogeEnd -> pogeAction
        }
    }
}

解説

まぁよくあるannotatedTextであれこれするやつなんですが

ClickableTextの返り値がoffsetで

クリックした箇所のoffsetを正確に返してくれるから

それに合わせてそれぞれアクション定義してあげれば色々出来るって感じですね


単純に指定のURL飛ばすだけならよくあるtagに入れてあれこれするやつがいいと思います

参考記事

https://developer.android.com/jetpack/compose/text?hl=ja

https://www.youtube.com/watch?v=yIKzs7a1Zog

Discussion