こんにちは。Android アプリ開発担当の nagayama(@nagayan_dev)です。
今回は Jetpack Compose で破線付きテキストの作り方をご紹介します。
テキストに線を加える表現方法にはさまざまな種類があります。強調したい場合は「下線」を、変更履歴を示したい場合は「取消線」を使うことが一般的です。その中でも、軽い強調として「破線」を加えたテキスト表現があります。今回は、この「破線付きのテキスト」をJetpack Composeで実現する方法をご紹介します。
まずは下線付きテキストについて解説します。
Text の引数でTextDecoration
を指定することができます。TextDecoration
は Text と一緒に描画する横線を設定するものになります。種類としては 下線 (Underline) と 取消線 (LineThrough) が用意されており、下記のように引数に指定するだけで簡単に描画することができます。
Column { Text( text = "下線", textDecoration = TextDecoration.Underline, ) Text( text = "取り消し線", textDecoration = TextDecoration.LineThrough, )}
では本題の破線付きテキストについてです。
残念ながら下線のように用意はされておらず、自作する必要があります。
方法としては、
とやっていきます。
破線の描画方法です。Canvas
を使用します。
まずCanvas
で線を描画するため、Canvas
のonDraw
でdrawLine
を行います。
主に設定するパラメータは下記になります。
横方向の線を描画するために、 start と end の引数に指定する Offset 型の y 値は同じsize.height
にし、 x 値を 0f からsize.width
に設定します。
線を破線にするために、pathEffect にPathEffect.dashPathEffect
を設定します。引数は
です。
実装は下記のようになります。
// 線の太さval strokeWidth: Float = 4f// 破線1つの長さval dashedLength: Float = 30f// 破線の間隔val dashedInterval: Float = 15fCanvas( modifier = Modifier .fillMaxSize(), onDraw = { drawLine( color = Color.Red, start = Offset(0f, size.height), end = Offset(size.width, size.height), strokeWidth = strokeWidth, cap = StrokeCap.Round, pathEffect = PathEffect.dashPathEffect( intervals = floatArrayOf(dashedLength, dashedInterval), phase = dashedLength + dashedInterval, ) ) })
続けて、先ほど作成した破線を Text の下に描画させます。
Column
を用いて上に Text を、下に破線を配置します。上記のコードをそのまま配置すると破線だけ大きく表示されてしまうため、modifier をModifier.matchParentSize()
に設定します。これによりText のサイズと合わせて表示してくれます。
Box { Text(text = "破線付きテキストの作り方") Canvas( modifier = Modifier .matchParentSize(), onDraw = { drawLine( ~省略~ ) } )}
以上が破線付きテキストの作成方法になります。
最後に Text の必要な引数を添えて、破線付きテキストを共通で使用できるよう Composable を作成します。
@Composablefun DashedText( text: String, modifier: Modifier = Modifier, color: Color = Color.Unspecified, fontSize: TextUnit = TextUnit.Unspecified, fontStyle: FontStyle? = null, fontWeight: FontWeight? = null, fontFamily: FontFamily? = null, letterSpacing: TextUnit = TextUnit.Unspecified, textDecoration: TextDecoration? = null, textAlign: TextAlign? = null, lineHeight: TextUnit = TextUnit.Unspecified, overflow: TextOverflow = TextOverflow.Clip, softWrap: Boolean = true, maxLines: Int = Int.MAX_VALUE, minLines: Int = 1, onTextLayout: ((TextLayoutResult) -> Unit)? = null, style: TextStyle = LocalTextStyle.current, // 破線の色 dashedColor: Color = Color.Unspecified, // 破線の太さ dashedWidth: Float = 4f, // 破線1つの長さ dashedLength: Float = 30f, // 破線の間隔 dashedInterval: Float = 15f) { Box( modifier = Modifier .wrapContentWidth(), contentAlignment = Alignment.BottomCenter ) { Text(text, modifier, color, fontSize, fontStyle, fontWeight, fontFamily, letterSpacing, textDecoration, textAlign, lineHeight, overflow, softWrap, maxLines, minLines, onTextLayout, style) Canvas( modifier = Modifier .matchParentSize() ) { drawLine( color = dashedColor, start = Offset(0f, size.height), end = Offset(size.width, size.height), strokeWidth = 2f, cap = StrokeCap.Round, pathEffect = PathEffect.dashPathEffect( intervals = floatArrayOf(dashedLength, dashedInterval), phase = dashedLength + dashedInterval, ) ) } }}
残念ながら今回ご紹介した破線付きテキストは 1 行のみの対応例になります。複数行を可能にするには描画するテキストの長さや行間隔を考慮する必要があります。
Jetpack Compose で破線付きテキストの作り方をご紹介しました。下線や取消線といったメジャーなテキストの表現を簡単に実現できる方法が用意されていました。また破線付きテキストといった特殊な表現でも、Canvas を活用することで綺麗に実装できます。Jetpack Compose の柔軟性と応用力の高さが感じられますね。これからも Jetpack Compose ライフを楽しみましょう。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。