Párrafo de estilo

En esta página, se describe cómo puedes aplicar diseño al texto de tu párrafo. Para establecer el diseño a nivel del párrafo, puedes configurar parámetros como textAlign y lineHeight, o definir tu propio ParagraphStyle.

Cómo establecer la alineación del texto

El parámetro textAlign te permite establecer la alineación horizontal del texto dentro de un área de superficie componible Text.

De forma predeterminada, Text seleccionará la alineación del texto natural según su valor de contenido:

  • Borde izquierdo del contenedor Text para alfabetos de izquierda a derecha, como el latino, el cirílico o el hangul
  • Borde derecho del contenedor Text para alfabetos de derecha a izquierda, como el árabe o el hebreo

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

Aparece la frase

Si quieres configurar manualmente la alineación del texto de un elemento componible Text, usa TextAlign.Start y TextAlign.End en lugar de TextAlign.Left y TextAlign.Right, respectivamente, ya que se resuelven en el borde derecho de Text, según la orientación de texto del idioma preferido. Por ejemplo, TextAlign.End se alinea con el lado derecho para el texto en francés y con el lado izquierdo para el texto en árabe, pero TextAlign.Right se alinea con el lado derecho, sin importar qué alfabeto se use.

Cómo agregar varios estilos en un párrafo

Para agregar varios estilos en un párrafo, puedes usar ParagraphStyle en un AnnotatedString, que se puede anotar con estilos de anotaciones arbitrarias. Una vez que una parte del texto se marca con un ParagraphStyle, esa parte queda separada del resto como si tuviera feeds de líneas al principio y al final.

Para obtener más información sobre cómo agregar varios estilos en un texto, consulta Agrega varios estilos en el texto.

AnnotatedString tiene un compilador de tipo seguro para facilitar la creación: buildAnnotatedString. En el siguiente fragmento, se usa buildAnnotatedString para configurar 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")
            }
        }
    )
}

Tres párrafos en tres estilos diferentes: azul, rojo y en negrita, y negro simple

Cómo ajustar la altura de la línea y el padding

includeFontPadding es una propiedad heredada que agrega padding adicional en función de las métricas de fuente en la parte superior de la primera línea y en la parte inferior de la última línea de un texto. A partir de la versión 2024.01.01 de la BoM de Compose, includeFontPadding se establece en false de forma predeterminada, lo que alinea el diseño de texto predeterminado con las herramientas de diseño comunes.

La capacidad de configurar lineHeight no es nueva. Está disponible desde Android Q. Puedes configurar lineHeight para Text mediante el parámetro lineHeight, que distribuye la altura de la línea en cada línea de texto. Luego, puedes usar el nuevo LineHeightStyle API para configurar aún más cómo se alinea este texto dentro del espacio y quitar los espacios en blanco.

Es posible que desees ajustar lineHeight mediante la unidad de texto "em" (tamaño de fuente relativo) en lugar de "sp" (píxeles ajustados) para mejorar la precisión. Para obtener más información sobre cómo seleccionar una unidad de texto adecuada, consulta TextUnit.

Imagen que muestra lineHeight como una medida según las líneas directamente arriba y abajo.
Figura 1: Usa Alignment y Trim para ajustar el texto dentro del lineHeight establecido y, si es necesario, recorta el espacio adicional.

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

Además de ajustar lineHeight, ahora puedes centrar más el texto y darle más estilo mediante los parámetros de configuración con la API experimental de LineHeightStyle: LineHeightStyle.Alignment y LineHeightStyle.Trim (includeFontPadding debe estar configurado como false para que Trim funcione). Alignment y Trim utilizan el espacio medido entre las líneas de texto para distribuirlo de manera más adecuada en todas las líneas, lo que incluye una sola línea de texto y la línea superior de un bloque de texto.

LineHeightStyle.Alignment define cómo alinear la línea en el espacio que proporciona la altura de la línea. Dentro de cada una, puedes alinear el texto en la parte superior, inferior, central o de forma proporcional. Luego, LineHeightStyle.Trim te permite dejar o quitar el espacio adicional en la parte superior de la primera línea y en la parte inferior de la última línea del texto, que se genera de cualquier ajuste de lineHeight y Alignment. En los siguientes ejemplos, se muestra cómo luce un texto de varias líneas con varios parámetros de configuración de LineHeightStyle.Trim cuando la alineación está centrada (LineHeightStyle.Alignment.Center).

Imagen que muestra LineHeightStyle.Trim.None Imagen que demuestra LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Imagen que muestra LineHeightStyle.Trim.FirstLineTop Imagen que muestra LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Consulta la entrada de blog Fixing Font Padding in Compose Text para obtener más información sobre el contexto de este cambio, el funcionamiento de includeFontPadding en el sistema View y los cambios que realizamos en Compose y las nuevas APIs de LineHeightStyle.

Inserta saltos de línea

La API de LineBreak define los criterios por los que el texto se divide en varias líneas. Puedes especificar el tipo de corte de línea que deseas en el bloque TextStyle de tu elemento componible Text. Los tipos de corte de línea preestablecidos incluyen los siguientes:

  • Simple: Salto de línea rápido y básico. Se recomienda para campos de entrada de texto.
  • Heading: Salto de línea con reglas de corte más flexibles. Se recomienda para texto corto, como títulos.
  • Paragraph: Saltos de línea más lentos y de mayor calidad para mejorar la legibilidad. Se recomienda para cantidades mayores de texto, como párrafos.

En el siguiente fragmento, se usan Simple y Paragraph para especificar el comportamiento de los saltos de línea en un bloque largo de texto:

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 bloque de texto que muestra una estrategia de corte de línea simple en comparación con un bloque de texto con una estrategia de corte optimizada para párrafos. El bloque de texto con la estrategia de corte de línea simple tiene más variabilidad en las longitudes de línea.
Figura 1: Un bloque de texto con una estrategia de saltos de línea simple (arriba) en comparación con un bloque de texto con saltos de línea optimizados para el párrafo (abajo).

En el resultado anterior, observa que el comportamiento de los saltos de línea de Paragraph produce un resultado más equilibrado visualmente que el de Simple.

Personaliza los saltos de línea

También puedes crear tu propia configuración de LineBreak con el parámetro Strategy. Strategy puede ser cualquiera de los siguientes:

  • Balanced: Intenta equilibrar las longitudes de línea del texto y también aplica la división automática de palabras si está habilitada. Se recomienda para pantallas pequeñas, como relojes, para maximizar la cantidad de texto que se muestra.
  • HighQuality: Optimiza un párrafo para que el texto sea más legible, incluida la división si está habilitada. (Debe ser un valor predeterminado para todo lo que no sea Balanced o Simple).
  • Simple: Estrategia básica y rápida. Si está habilitada, la división en sílabas se realiza solo para las palabras que no caben en una línea completa por sí solas. Es útil para editar texto y evitar cambiar de posición mientras escribes.

En el siguiente fragmento, se muestra la diferencia entre un párrafo con la configuración predeterminada y un párrafo optimizado para pantallas pequeñas con la estrategia de saltos de línea 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 párrafo con una estrategia equilibrada de saltos de línea y un párrafo con formato sin una estrategia El párrafo con la estrategia de saltos de línea equilibrados tiene longitudes de línea más coherentes que el predeterminado.
Figura 2: Un párrafo con formato de una estrategia de saltos de línea Balanced (arriba) en comparación con un párrafo con formato sin una estrategia de saltos de línea.

Consideraciones de CJK

También puedes personalizar LineBreak con las APIs de Strictness y WordBreak, que se diseñaron específicamente para los idiomas CJK. Es posible que no siempre veas los efectos de estas APIs en idiomas que no sean CJK. En general, las reglas de saltos de línea se definen según la configuración regional.

Strictness describe la rigidez de los saltos de línea con las siguientes propiedades:

  • Default: Son las reglas de división predeterminadas para la configuración regional. Puede corresponder a Normal o Strict.
  • Loose: Son las reglas menos restrictivas. Adecuada para líneas cortas.
  • Normal: Son las reglas más comunes para el corte de línea.
  • Strict: Son las reglas más estrictas para el corte de línea.

WordBreak define cómo se deben insertar los saltos de línea dentro de las palabras con las siguientes propiedades:

  • Default: Son las reglas de división predeterminadas para la configuración regional.
  • Phrase: El corte de línea se basa en frases.

En el siguiente fragmento, se usa una rigidez Strict y una configuración de división de palabras Phrase para un texto en japonés:

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

Texto japonés con configuración de Strictness y WordBreak en comparación con el texto predeterminado.
Figura 3: Texto con formato Strictness y configuración WordBreak (arriba) en comparación con texto con formato solo LineBreak.Heading (abajo).

Cómo guionar el texto dividido en líneas

La API de Hyphens te permite agregar compatibilidad con la división en sílabas a tu app. La división en sílabas consiste en insertar un signo de puntuación similar a un guion para indicar que una palabra se divide en líneas de texto. Cuando está habilitada, se agrega la división entre las sílabas de una palabra en los puntos de división adecuados.

De forma predeterminada, la división en sílabas no está habilitada. Para habilitar la división en sílabas, agrega Hyphens.Auto como parámetro en un bloque 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 párrafo sin habilitación de la división en sílabas y un párrafo con habilitación de la división en sílabas.
  Cuando se habilita la división en sílabas, una palabra se divide en dos líneas.
Figura 4: Un párrafo sin la división en sílabas habilitada (arriba) en comparación con un párrafo con la división en sílabas habilitada (abajo).

Cuando está habilitada, la división en sílabas solo se produce en las siguientes condiciones:

  • Una palabra no cabe en una línea. Si usas una estrategia de corte de línea Simple, la división en sílabas de una palabra ocurre solo si una línea es más corta que la palabra única.
  • La configuración regional adecuada se establece en tu dispositivo, ya que la división en sílabas adecuada se determina con los diccionarios presentes en el sistema.