スタイル段落

このページでは、段落のテキストにスタイルを設定する方法について説明します。段落レベルのスタイルを設定するには、textAlignlineHeight などのパラメータを構成するか、独自の ParagraphStyle を定義します。

テキストの配置を設定する

textAlign パラメータを使用すると、Text コンポーザブルのサーフェス領域内のテキストの水平方向の位置揃えを設定できます。

デフォルトでは、Text はコンテンツの値に応じて自然なテキストの配置を選択します。

  • Text コンテナの左端: ラテン文字、キリル文字、ハングルなど、左から右に記述するアルファベットの場合
  • Text コンテナの右端: アラビア語やヘブライ語など、右から左に記述するアルファベットの場合

@Composable
fun CenterText() {
    Text(
        "Hello World", textAlign = TextAlign.Center, modifier = Modifier.width(150.dp)
    )
}

単語

Text コンポーザブルのテキスト配置を手動で設定する場合は、優先言語のテキストの向きに応じて Text コンポーザブルの右端に解決されるため、TextAlign.LeftTextAlign.Right の代わりに、それぞれ TextAlign.StartTextAlign.End を使用することをおすすめします。たとえば、TextAlign.End では、フランス語テキストは右側、アラビア語テキストは左側に配置されます。一方、TextAlign.Right では、使用されているアルファベットの種類にかかわらず、テキストが右側に配置されます。

段落に複数のスタイルを追加する

段落に複数のスタイルを追加するには、AnnotatedStringParagraphStyle を使用します。これにより、任意のアノテーションのスタイルを設定できます。テキストの一部を ParagraphStyle でマークすると、その部分は、先頭と末尾にラインフィードがあるように残りのテキストから分離されます。

テキストに複数のスタイルを追加する方法については、テキストに複数のスタイルを追加するをご覧ください。

AnnotatedString には、タイプセーフなビルダーがあり、buildAnnotatedString を簡単に作成できます。次のスニペットでは、buildAnnotatedString を使用して ParagraphStyle を設定しています。

@Composable
fun ParagraphStyle() {
    Text(
        buildAnnotatedString {
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
                withStyle(style = SpanStyle(color = Color.Blue)) {
                    append("Hello\n")
                }
                withStyle(
                    style = SpanStyle(
                        fontWeight = FontWeight.Bold, color = Color.Red
                    )
                ) {
                    append("World\n")
                }
                append("Compose")
            }
        }
    )
}

3 つの段落を 3 種類のスタイル(青色、赤色と太字、黒色)で表示

行の高さとパディングを調整する

includeFontPadding は、フォント指標に基づいてテキストの最初の行の上と最後の行の下にパディングを追加するレガシー プロパティです。Compose BOM バージョン 2024.01.01 以降、includeFontPadding はデフォルトで false に設定されます。これにより、デフォルトのテキスト レイアウトは、一般的なデザインツールに近くなります。

lineHeight を設定する機能は新しいものではなく、Android Q 以降で利用できます。TextlineHeight を設定するには、lineHeight パラメータを使用します。これにより、テキストの各行で行の高さが割り振られます。その後、新しい LineHeightStyle API を使用して、スペース内でのテキストの配置方法をさらに設定し、空白文字を削除できます。

精度を高めるために、テキストの単位に「sp」(スケール非依存ピクセル)ではなく「em」(相対的なフォントサイズ)を使用して lineHeight を調整することをおすすめします。適切なテキスト単位の選択について詳しくは、TextUnit をご覧ください。

真上と真下の行に基づいた測定値として lineHeight を示す画像。
図 1.Alignment と Trim を使用して、セット lineHeight 内のテキストを調整し、必要に応じて余分なスペースを削除します。

Text(
    text = text,
    style = LocalTextStyle.current.merge(
        TextStyle(
            lineHeight = 2.5.em,
            platformStyle = PlatformTextStyle(
                includeFontPadding = false
            ),
            lineHeightStyle = LineHeightStyle(
                alignment = LineHeightStyle.Alignment.Center,
                trim = LineHeightStyle.Trim.None
            )
        )
    )
)

lineHeight の調整に加えて、LineHeightStyle 試験運用版 API の構成(LineHeightStyle.AlignmentLineHeightStyle.Trim)を使用して、テキストの中央揃えとスタイル設定をさらに行うことができるようになりました(Trim が機能するには includeFontPaddingfalse に設定する必要があります)。Alignment と Trim は、テキストの行間にある測定されたスペースを使用し、1 行のテキストやテキストのブロックの一番上の行を含め、すべての行にスペースをさらに適切に割り振ります。

LineHeightStyle.Alignment は、行の高さによって指定されるスペース内の行の配置方法を定義します。各行内で、テキストを上、下、中央に、または比例して配置できます。LineHeightStyle.Trim を使用すると、lineHeight と Alignment の調整から生成された、テキストの 1 行目の上と最後の行の下の追加のスペースを残すか削除できます。次のサンプルは、アライメントが中央に配置されたとき(LineHeightStyle.Alignment.Center)に、さまざまな LineHeightStyle.Trim 構成で複数行のテキストがどのように表示されるかを示しています。

LineHeightStyle.Trim.None を示す画像 LineHeightStyle.Trim.Both を示す画像
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
LineHeightStyle.Trim.FirstLineTop を示す画像 LineHeightStyle.Trim.LastLineBottom を示す画像
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

この変更のコンテキスト、View システムでの includeFontPadding の仕組み、Compose と新しい LineHeightStyle API の変更点について詳しくは、Compose テキストのフォント パディングの修正に関するブログ投稿をご覧ください。

改行を挿入

LineBreak API は、テキストを複数の行に分割する際の条件を定義します。必要な改行の種類は、Text コンポーザブルの TextStyle ブロックで指定できます。プリセットの改行タイプには次のものがあります。

  • Simple - 高速で基本的な改行。テキスト入力フィールドに推奨されます。
  • Heading - 緩やかな改行で区切られます。タイトルなど、短いテキストにおすすめします。
  • Paragraph - 低速で高品質な改行コード。読みやすさが向上します。 段落など、テキストの量が多い場合におすすめします。

次のスニペットでは、SimpleParagraph の両方を使用して、長いテキスト ブロックの改行動作を指定しています。

TextSample(
    samples = mapOf(
        "Simple" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Simple
                )
            )
        },
        "Paragraph" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph
                )
            )
        }
    )
)

単純な改行戦略と、段落の最適化を使用したテキスト ブロック戦略を示すテキスト ブロック。単純な改行戦略のテキスト ブロックでは、行の長さにばらつきがあります。
図 1. シンプルな改行戦略を使用したテキスト ブロック(上)と、段落に最適化された改行を使用したテキスト ブロック(下)

上記の出力では、Paragraph の改行動作の方が、Simple の改行よりも見た目のバランスが取れた結果になります。

改行をカスタマイズする

Strategy パラメータを使用して独自の LineBreak 構成を作成することもできます。Strategy は次のいずれかです。

  • Balanced - テキストの行のバランスをとります。有効になっている場合は、自動ハイフネーションも適用されます。表示されるテキストの量を最大化するために、スマートウォッチなどの小さな画面におすすめします。
  • HighQuality - テキストが読みやすくなるように段落を最適化します。有効にする場合はハイフンを付けます。(Balanced または Simple 以外のすべてのデフォルトになります)。
  • Simple - 基本的かつ迅速な戦略。有効にすると、それだけでは 1 行に収まらない単語に対してのみハイフネーションが行われます。入力中に位置を変更しないようにテキストを編集する場合に便利です。

次のスニペットは、デフォルト設定の段落と、Balanced の改行戦略を使用して小さい画面向けに最適化された段落の違いを示しています。

TextSample(
    samples = mapOf(
        "Balanced" to {
            val smallScreenAdaptedParagraph =
                LineBreak.Paragraph.copy(strategy = LineBreak.Strategy.Balanced)
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(200.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = smallScreenAdaptedParagraph
                )
            )
        },
        "Default" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(200.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default
            )
        }
    )
)

バランスの取れた改行戦略が適用された段落と、戦略が設定されていない段落。バランスの取れた改行戦略を使用している段落では、デフォルトよりも行の長さが統一されます。
図 2. Balanced の改行戦略(上)で書式設定された段落と、改行戦略なしで書式設定された段落。

CJK に関する考慮事項

また、CJK 言語専用に設計された Strictness API と WordBreak API を使用して LineBreak をカスタマイズすることもできます。CJK 以外の言語では、これらの API の影響が常に確認できるとは限りません。概して、改行ルールはロケールに基づいて定義されます。

Strictness は、次のプロパティを使用して改行の厳格さを記述します。

  • Default - ロケールのデフォルトの違反ルール。Normal または Strict に対応する場合があります。
  • Loose - 最も制限の少ないルール。短い行列に適している。
  • Normal - 改行の最も一般的なルール。
  • Strict - 改行で最も厳格なルール。

WordBreak は次のプロパティを使用して、単語内に改行をどのように挿入するかを定義します。

  • Default - ロケールのデフォルトの違反ルール。
  • Phrase - フレーズに基づいて改行します。

次のスニペットでは、日本語のテキストに対して Strict の厳格さと Phrase の単語区切り設定を使用しています。

val customTitleLineBreak = LineBreak(
    strategy = LineBreak.Strategy.HighQuality,
    strictness = LineBreak.Strictness.Strict,
    wordBreak = LineBreak.WordBreak.Phrase
)
Text(
    text = "あなたに寄り添う最先端のテクノロジー。",
    modifier = Modifier.width(250.dp),
    fontSize = 14.sp,
    style = TextStyle.Default.copy(
        lineBreak = customTitleLineBreak
    )
)

「厳格」および「ワードブレーク」設定を適用した日本語のテキストと、デフォルトのテキスト
図 3. Strictness および WordBreak 設定でフォーマットされたテキスト(上)と、LineBreak.Heading のみでフォーマットされたテキスト(下)。

行を分割したテキストをハイフンで囲む

Hyphens API を使用すると、アプリにハイフネーションのサポートを追加できます。ハイフンとは、ダッシュのような句読点を挿入して、単語がテキスト行に分割されていることを示します。有効にすると、単語の音節間の適切なハイフネーション ポイントでハイフネーションが追加されます。

デフォルトでは、ハイフネーションは有効になっていません。ハイフネーションを有効にするには、TextStyle ブロックにパラメータとして Hyphens.Auto を追加します。

TextSample(
    samples = mapOf(
        "Hyphens - None" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph,
                    hyphens = Hyphens.None
                )
            )
        },
        "Hyphens - Auto" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph,
                    hyphens = Hyphens.Auto
                )
            )
        }
    )
)

ハイフネーションが有効になっていない段落と、ハイフネーションが有効になっている段落。ハイフネーションを有効にすると、単語がハイフネーションされ、2 行に分割されます。
図 4. ハイフネーションを有効にしていない段落(上)とハイフネーションが有効になっている段落(下)

有効にすると、ハイフネーションは次の条件下でのみ発生します。

  • 1 行に収まらない単語です。Simple の改行戦略を使用する場合、単語のハイフネーションは、行が 1 つの単語よりも短い場合にのみ行われます。
  • 適切なロケールがデバイスに設定されており、適切なハイフネーションはシステム上の辞書を使用して決定されます。