スタイル段落

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

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

textAlign パラメータを使用すると、Text コンポーザブルの面積内でのテキストの水平配置を設定できます。

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

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

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

単語

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

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

段落に複数のスタイルを追加するには、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.Alignment および LineHeightStyle.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

この変更の背景、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 をカスタマイズすることもできます。これらの API の効果は、CJK 以外の言語では必ずしも現れない場合があります。全体として、改行ルールはロケールに基づいて定義されます。

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. StrictnessWordBreak の設定で書式設定されたテキスト(上)と、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 の行折り返し戦略を使用する場合、単語のハイフネーションは、行が単語よりも短い場合にのみ行われます。
  • 適切なハイフネーションはシステムに存在する辞書を使用して決定されるため、デバイスに適切なロケール設定がされています。