Stile paragrafo

In questa pagina viene descritto come applicare uno stile al testo del paragrafo. Per impostare gli stili a livello di paragrafo, puoi configurare parametri come textAlign e lineHeight o definire i tuoi ParagraphStyle.

Imposta allineamento del testo

Il parametro textAlign consente di impostare l'allineamento orizzontale del testo all'interno di un'area componibile di Text.

Per impostazione predefinita, Text selezionerà l'allineamento naturale del testo in base al valore del contenuto:

  • Bordo sinistro del contenitore Text per alfabeti da sinistra a destra come latino, cirillico o hangul
  • Bordo destro del contenitore Text per alfabeti da destra a sinistra come arabo o ebraico

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

Le parole

Se vuoi impostare manualmente l'allineamento del testo di un componibile Text, preferisci utilizzare TextAlign.Start e TextAlign.End rispettivamente anziché TextAlign.Left e TextAlign.Right, poiché si trovano sul bordo destro dell'elemento componibile Text, a seconda dell'orientamento del testo nella lingua preferita. Ad esempio, TextAlign.End si allinea al lato destro per il testo in francese e al lato sinistro per il testo in arabo, mentre TextAlign.Right si allinea al lato destro per il testo in francese, indipendentemente dall'alfabeto utilizzato.

Aggiungere più stili in un paragrafo

Per aggiungere più stili in un paragrafo, puoi usare ParagraphStyle in una AnnotatedString, che può essere annotata con stili di annotazioni arbitrarie. Quando una parte del testo viene contrassegnata con un ParagraphStyle, questa viene separata dal testo rimanente come se avesse un avanzamento riga all'inizio e alla fine.

Per ulteriori informazioni sull'aggiunta di più stili in un testo, consulta la sezione Aggiungere più stili nel testo.

AnnotatedString ha uno strumento di creazione tipo-safe per semplificare la creazione di: buildAnnotatedString. Il seguente snippet utilizza buildAnnotatedString per impostare 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")
            }
        }
    )
}

Tre paragrafi in tre stili diversi: blu, rosso, in grassetto e nero semplice

Regola l'altezza della riga e la spaziatura interna

includeFontPadding è una proprietà precedente che aggiunge spaziatura interna extra in base alle metriche dei caratteri nella parte superiore della prima riga e nella parte inferiore dell'ultima riga di un testo. A partire dalla versione 2024.01.01 di Compose BOM, il valore predefinito di includeFontPadding è false, in modo da allineare il layout di testo predefinito con gli strumenti di progettazione più comuni.

La possibilità di configurare lineHeight non è nuova: è disponibile da Android Q. Puoi configurare lineHeight per Text utilizzando il parametro lineHeight, che distribuisce l'altezza della riga in ogni riga di testo. Puoi quindi utilizzare il nuovo LineHeightStyle API per configurare ulteriormente l'allineamento del testo all'interno dello spazio e rimuovere gli spazi vuoti.

Ti consigliamo di modificare lineHeight utilizzando l'unità di testo "em" (dimensioni del carattere relative) anziché "sp" (pixel in scala) per una maggiore precisione. Per ulteriori informazioni sulla selezione di un'unità di testo appropriata, consulta TextUnit.

Immagine che mostra l'altezza della linea come misura in base alle linee direttamente sopra e sotto di essa.
Figura 1. Usa Allinea e Taglia per regolare il testo nel set lineHeight e, se necessario, tagliare altro spazio.

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
            )
        )
    )
)

Oltre a modificare lineHeight, ora puoi centrare ulteriormente e definire lo stile del testo utilizzando le configurazioni con l'API sperimentale LineHeightStyle: LineHeightStyle.Alignment e LineHeightStyle.Trim (affinché Taglia funzioni, includeFontPadding deve essere impostato su false). Allineamento e Taglia utilizzano lo spazio misurato tra le righe di testo per distribuirlo in modo più appropriato su tutte le righe, inclusa una singola riga di testo e la prima riga di un blocco di testo.

LineHeightStyle.Alignment definisce come allineare la linea nello spazio fornito dall'altezza della riga. All'interno di ogni riga, puoi allineare il testo in alto, in basso, al centro o in modo proporzionale. LineHeightStyle.Trim ti consente quindi di lasciare o rimuovere lo spazio aggiuntivo nella parte superiore della prima riga e nella parte inferiore dell'ultima riga del testo, generato a partire da eventuali regolazioni lineHeight e di allineamento. I seguenti esempi mostrano l'aspetto del testo su più righe con varie configurazioni di LineHeightStyle.Trim quando l'allineamento è centrato (LineHeightStyle.Alignment.Center).

Un'immagine che mostra LineHeightStyle.Trim.None Un'immagine che mostra LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Un'immagine che mostra LineHeightStyle.Trim.FirstLineTop Un'immagine che mostra LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Consulta il post del blog Correzione del riempimento dei caratteri nel testo di Compose per scoprire di più sul contesto di questa modifica, sul funzionamento di includeFontPadding nel sistema View e sulle modifiche apportate per Compose e le nuove API LineHeightStyle.

Inserisci interruzioni di riga

L'API LineBreak definisce i criteri in base ai quali il testo viene suddiviso su più righe. Puoi specificare il tipo di interruzione di riga che vuoi nel blocco TextStyle del componibile Text. I tipi di interruzione di riga preimpostati includono:

  • Simple: interruzione rapida ed essenziale. Opzione consigliata per i campi di immissione testo.
  • Heading - Interruzione di riga con regole di interruzione meno restrittive. Consigliato per i testi brevi, come i titoli.
  • Paragraph: interruzione di riga più lenta e di qualità superiore per una migliore leggibilità. Opzione consigliata per quantità di testo maggiori, come i paragrafi.

Lo snippet seguente utilizza sia Simple sia Paragraph per specificare un comportamento di interruzione di riga su un blocco di testo lungo:

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
                )
            )
        }
    )
)

Un blocco di testo che mostra una strategia di interruzione di riga semplice rispetto a un blocco di testo con una strategia di interruzione ottimizzata per i paragrafi. Il blocco di testo con la strategia
di interruzione di riga semplice presenta una maggiore variabilità nella lunghezza delle righe.
Figura 1. Un blocco di testo con una semplice strategia di interruzione di riga (in alto) rispetto a un blocco di testo con interruzione di riga ottimizzata per il paragrafo (in basso).

Nell'output riportato sopra, nota che il comportamento di interruzione di riga Paragraph produce un risultato visivamente più bilanciato rispetto all'interruzione di riga Simple.

Personalizzare le interruzioni di riga

Puoi anche creare la tua configurazione LineBreak con il parametro Strategy. Strategy può essere uno dei seguenti:

  • Balanced: tenta di bilanciare le lunghezze delle righe del testo applicando anche la sillabazione automatica, se abilitata. Consigliato per schermi di piccole dimensioni, come gli orologi, per massimizzare la quantità di testo visualizzato.
  • HighQuality: ottimizza un paragrafo per offrire un testo più leggibile, incluso i trattini, se attivati. (Deve essere un valore predefinito per tutto ciò che non è Balanced o Simple.)
  • Simple: strategia di base rapida. Se attivata, i trattini vengono applicati solo per le parole che non rientrano in un'intera riga. Utile per modificare il testo e evitare di cambiare posizione durante la digitazione.

Lo snippet seguente mostra la differenza tra un paragrafo con impostazioni predefinite e un paragrafo ottimizzato per schermi di piccole dimensioni con la strategia di interruzione di riga 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
            )
        }
    )
)

Un paragrafo con una strategia di interruzione di riga bilanciata e un paragrafo formattato senza una strategia. Il paragrafo con la strategia di interruzione di riga bilanciata presenta lunghezze di riga più coerenti rispetto a quella predefinita.
Figura 2. Un paragrafo formattato con una strategia di interruzione di riga Balanced (in alto) rispetto a un paragrafo formattato senza una strategia di interruzione di riga.

Considerazioni su CJK

Puoi anche personalizzare LineBreak con le API Strictness e WordBreak, che sono state progettate appositamente per i linguaggi CJK. Potresti non vedere sempre gli effetti di queste API in lingue non CJK. In generale, le regole di interruzione di riga sono definite in base alle impostazioni internazionali.

Strictness descrive il livello di interruzione della linea con le seguenti proprietà:

  • Default: regole di interruzione predefinite per le impostazioni internazionali. Può corrispondere a Normal o Strict.
  • Loose: le regole meno restrittive. Adatto a righe brevi.
  • Normal: le regole più comuni per l'interruzione di riga.
  • Strict: le regole più rigorose per l'interruzione di riga.

WordBreak definisce in che modo le interruzioni di riga devono essere inserite all'interno delle parole con le seguenti proprietà:

  • Default: regole di interruzione predefinite per le impostazioni internazionali.
  • Phrase: l'interruzione di riga si basa su frasi.

Lo snippet seguente utilizza una severità Strict e un'impostazione di interruzione delle parole Phrase per un testo in giapponese:

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
    )
)

Testo giapponese con impostazioni di Severità e WordBreak rispetto al testo predefinito.
Figura 3. Testo formattato con le impostazioni Strictness e WordBreak (in alto) rispetto al testo formattato solo con LineBreak.Heading (in basso).

Tratteggiato diviso tra le righe

L'API Hyphens ti consente di aggiungere il supporto della sillabazione all'app. Per sintassi si intende l'inserimento di un segno di punteggiatura simile a un trattino per indicare che una parola è divisa tra righe di testo. Quando questa opzione è abilitata, viene aggiunta sillabica tra le sillabe di una parola.

Per impostazione predefinita, la sillabazione non è abilitata. Per attivare la sillabazione, aggiungi Hyphens.Auto come parametro in un blocco TextStyle:

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
                )
            )
        }
    )
)

Un paragrafo senza sillabazione attivata e un paragrafo con sillabazione attivata.
  Quando è attiva la sillabazione, il trattino viene diviso su due righe.
Figura 4. Un paragrafo senza sillabazione attivata (in alto) e un paragrafo con sillabazione abilitata (in basso).

Quando questa opzione è abilitata, la sillabazione si verifica solo alle seguenti condizioni:

  • Una parola non rientra in una riga. Se utilizzi una strategia di interruzione di riga Simple, la sillabazione di una parola si verifica solo se una riga è più corta della singola parola.
  • Sul dispositivo sono impostate le impostazioni internazionali appropriate, che viene determinata la sillabazione appropriata mediante i dizionari presenti nel sistema.