Jetpack Composeでテキストの中にアイコンを埋め込んで表示させる
Jetpack Compose では簡単にテキストの中にアイコンを埋め込むことができたので紹介しようと思います。
実装コード
早速サンプルコードから
@Composable
fun Example() {
val iconId = "iconId"
Text(
text = buildAnnotatedString {
appendInlineContent(iconId)
append("Hoge")
appendInlineContent(iconId)
append("Fuga")
},
inlineContent = mapOf(
iconId to InlineTextContent(
placeholder = Placeholder(
width = 24.sp,
height = 24.sp,
placeholderVerticalAlign = PlaceholderVerticalAlign.TextCenter,
),
children = {
Icon(
painter = painterResource(id = R.drawable.ic_android),
contentDescription = null,
)
},
),
),
)
}
上記のコードを動かすとテキストの中にアイコンを表示させることができます。
テキストが長い場合でもアイコンがテキストの中に埋め込まれる形になるので、改行された後のテキストとアイコンのラインを揃えるデザインにも対応できます。
ざっくり実装を説明すると、
- 表示させたいアイコンのキーとなる文字列を定義
-
InlineTextContent
にコンテンツを表示させる領域の指定と、表示させたいコンテンツの Composable を設定する -
Text
のinlineContent
に定義したキーとInlineTextContent
をPair
で関連づけて渡す -
buildAnnotatedString
の中で表示したいタイミングでappendInlineContent
に定義したキーとなる文字列を渡すとText
の中でInlineTextContent
で設定した Composable が表示される
という感じになっています。
アイコン以外を表示する
@Composable
fun Circle(
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
) {
Canvas(modifier = modifier) {
drawCircle(
color = color,
)
}
}
@Composable
fun Example() {
val iconId = "iconId"
val circleId = "circleId"
Text(
text = buildAnnotatedString {
appendInlineContent(iconId)
append("Hoge")
appendInlineContent(circleId)
append("Fuga")
},
inlineContent = mapOf(
iconId to InlineTextContent(
Placeholder(
width = 24.sp,
height = 24.sp,
placeholderVerticalAlign = PlaceholderVerticalAlign.TextCenter,
),
children = {
Icon(
painter = painterResource(id = R.drawable.ic_android),
contentDescription = null,
)
},
),
circleId to InlineTextContent(
placeholder = Placeholder(
width = 10.sp,
height = 10.sp,
placeholderVerticalAlign = PlaceholderVerticalAlign.TextCenter,
),
children = {
Circle(
Modifier.size(8.dp)
)
},
)
),
)
}
上記のコードを動かすと以下のようになり、Icon
以外でも表示させることができて、複数のコンテンツをテキストの中に表示させることができます。
アイコンが含まれるテキストの読み上げについて
appendInlineContent()
にはキーとなる文字列以外にも alternateText
を設定できるようになっており、Talkback で読み上げる場合はこの alternateText
が読み上げられます。
Text(
text = buildAnnotatedString {
appendInlineContent(iconId, "Android")
append("Hoge")
appendInlineContent(iconId)
append("Fuga")
},
)
このコードの場合は
Android Hoge Fuga
と読み上げられます。
コンテンツ側の Icon
に contentDescription
を設定した場合は、 contentDescription
がテキストの読み上げられた最後にまとめて読み上げられます。
Text(
text = buildAnnotatedString {
appendInlineContent(iconId)
append("Hoge")
appendInlineContent(iconId)
append("Fuga")
},
inlineContent = mapOf(
iconId to InlineTextContent(
placeholder = Placeholder(
width = 24.sp,
height = 24.sp,
placeholderVerticalAlign = PlaceholderVerticalAlign.TextCenter,
),
children = {
Icon(
painter = painterResource(id = R.drawable.ic_android),
contentDescription = "Android",
)
},
),
),
)
このコードの場合は
Hoge Fuga Android画像 Android画像
と読み上げられます。
そのため、appendInlineContent
を使う場合のテキストの読み上げは、 appendInlineContent
の alternateText
で自然なテキストになるようにするか、Text
自体の semantics
で設定してあげるのが良さそうです。
参考
Author And Source
この問題について(Jetpack Composeでテキストの中にアイコンを埋め込んで表示させる), 我々は、より多くの情報をここで見つけました https://qiita.com/Nabe1216/items/6cff21e9ea60fd4de2b5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .