¿En qué circunstancias funciona la propiedad textAlign en Flutter?


83

En el código siguiente, la textAlignpropiedad no funciona. Si quita el DefaultTextStyleenvoltorio que está varios niveles por encima, textAligncomienza a funcionar.

¿Por qué y cómo asegurarse de que siempre esté funcionando?

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new DefaultTextStyle(style: new TextStyle(fontSize: 10.0), child: new Column(children: <Widget>[
        new Text("Should be left", textAlign: TextAlign.left,),
        new Text("Should be right", textAlign: TextAlign.right,)
      ],))
    );
  }
}

Ambos enfoques, sugeridos por Remi, aparentemente no funcionan "en la naturaleza". Aquí hay un ejemplo que anidé tanto dentro de filas como de columnas. El primer enfoque no se alinea y el segundo enfoque hace que la aplicación simplemente se bloquee:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new Directionality(textDirection: TextDirection.ltr, child: new DefaultTextStyle(
            style: new TextStyle(fontSize: 10.0, color: Colors.white),
            child: new Column(children: <Widget>[
              new Row(children: <Widget>[
                new Container(color: Colors.grey, child: new Column(children: <Widget>[
                  new Align(alignment: Alignment.centerLeft, child: new Text("left")),
                  new Align(alignment: Alignment.centerRight, child: new Text("right")),
                ],)),
                new Container(color: Colors.grey, child: new Column(children: <Widget>[
                  new Align(alignment: Alignment.centerLeft, child: new Text("left")),
                  new Align(alignment: Alignment.centerRight, child: new Text("right")),
                ],)),
              ],),
              /*new Row(children: <Widget>[
                new Container(color: Colors.grey, child: new Column(children: <Widget>[
                  new SizedBox(width: double.infinity, child: new Text("left", textAlign: TextAlign.left,)),
                  new SizedBox(width: double.infinity, child: new Text("right", textAlign: TextAlign.right)),
                ],)),
                new Container(color: Colors.grey, child: new Column(children: <Widget>[
                  new SizedBox(width: double.infinity, child: new Text("left", textAlign: TextAlign.left)),
                  new SizedBox(width: double.infinity, child: new Text("right", textAlign: TextAlign.right)),
                ],)),
              ],)*/]
    )));
  }
}

Lo que obtengo del código es

ingrese la descripción de la imagen aquí

es decir, el texto está centrado, ignorando la alineación del Alignelemento.


¿Por qué utiliza DefaultTextStyle como contenedor para 2 elementos secundarios de texto?
diegoveloper

2
¿Por qué no lo haría?
Atenúa el

Respuestas:


172

DefaultTextStyleno está relacionado con el problema. Eliminarlo simplemente usa el estilo predeterminado, que es mucho más grande que el que usó, por lo que oculta el problema.


textAlignalinea el texto en el espacio ocupado por Textcuando ese espacio ocupado es más grande que el contenido real.

La cuestión es que, dentro de un Column, Textocupa el mínimo espacio. Entonces es el Columnque alinea a sus hijos con el crossAxisAlignmentque por defecto center.

Una manera fácil de detectar tal comportamiento es envolver sus textos de esta manera:

Container(
   color: Colors.red,
   child: Text(...)
)

Que usando el código que proporcionó, renderice lo siguiente:

ingrese la descripción de la imagen aquí

El problema de repente se vuelve obvio: Textno tome todo el Columnancho.


Ahora tiene algunas soluciones.

Usted puede envolver su Texten una Alignde imitar textAlignel comportamiento

Column(
  children: <Widget>[
    Align(
      alignment: Alignment.centerLeft,
      child: Container(
        color: Colors.red,
        child: Text(
          "Should be left",
        ),
      ),
    ),
  ],
)

Que generará lo siguiente:

ingrese la descripción de la imagen aquí

o puedes forzar tu Texta llenar el Columnancho.

Ya sea especificando crossAxisAlignment: CrossAxisAlignment.stretchen Columno usando SizedBoxcon un infinito width.

Column(
  children: <Widget>[
    SizedBox(
      width: double.infinity,
      child: Container(
        color: Colors.red,
        child: Text(
          "Should be left",
          textAlign: TextAlign.left,
        ),
      ),
    ),
  ],
),

que rinde lo siguiente:

ingrese la descripción de la imagen aquí

En ese ejemplo, es el TextAlignque colocó el texto a la izquierda.


1
¿Pero no estás de acuerdo en que todo lo que describiste son trucos y soluciones, es decir, un mal diseño de la biblioteca?
atenúa el

3
Definitivamente, esto no es un truco / solución. Esta es la solución oficial. Flutter usa un diseño basado en restricciones con la composición en su núcleo. Es la programación funcional de Layout. Es absolutamente increíble
Rémi Rousselet

1
En el primer caso, especificó "izquierda" dos veces, en el segundo caso especificó un ancho infinito. Definitivamente son trucos a pesar de ser oficiales y funcionales.
Atenúa el

1
Ah, lo siento, olvidé quitar textAlignel Alignejemplo. Fijo. Y el "ancho infinito" en aleteo simplemente dice "Quiero tanto espacio como sea posible".
Rémi Rousselet

Bien, entonces la primera forma es mejor, aunque todavía no funciona para mí fuera de este simple ejemplo ...
Atenúa el

56

Especifique crossAxisAlignment: CrossAxisAlignment.starten su columna


1
¿No debería ser eso ?: crossAxisAlignment: CrossAxisAlignment.start
Keplerian

Eso no funcionaría ya que tiene un widget de texto alineado a la izquierda y otro a la derecha ...
Hasen

@TSR esto solo funciona si la columna ya tiene un elemento que ocupa todo el ancho (por ejemplo Row, a funcionaría, oAlign( ... centerLeft)
TSR

16

textAlignLa propiedad solo funciona cuando queda más espacio para el Textcontenido de. A continuación se muestran 2 ejemplos que muestran cuándo textAlign tiene impacto y cuándo no.


Sin impacto

Por ejemplo, en este ejemplo, no tendrá ningún impacto porque no hay espacio adicional para el contenido del Text.

Text(
  "Hello",
  textAlign: TextAlign.end, // no impact
),

ingrese la descripción de la imagen aquí


Tiene impacto

Si lo envuelve en un Containery proporciona un extra de widthmodo que tenga más espacio extra.

Container(
  width: 200,
  color: Colors.orange,
  child: Text(
    "Hello",
    textAlign: TextAlign.end, // has impact
  ),
)

ingrese la descripción de la imagen aquí


También puede probarlo conVery \n Good Morning
CopsOnRoad

10

En el widget Colum, la alineación del texto se centrará automáticamente, así crossAxisAlignment: CrossAxisAlignment.startque úsela para iniciar la alineación.

Column( 
    crossAxisAlignment: CrossAxisAlignment.start, 
    children: <Widget>[ 
    Text(""),
    Text(""),
    ]);

3

Colocado alignment: Alignment.centerRighten contenedor:

Container(
    alignment: Alignment.centerRight,
    child:Text(
       "Hello",
    ),
)

1

Para una máxima flexibilidad, normalmente prefiero trabajar con SizedBox así:

Row(
                                children: <Widget>[
                                  SizedBox(
                                      width: 235,
                                      child: Text('Hey, ')),
                                  SizedBox(
                                      width: 110,
                                      child: Text('how are'),
                                  SizedBox(
                                      width: 10,
                                      child: Text('you?'))
                                ],
                              )

He tenido problemas con la alineación del texto al usar la alineación en el pasado, mientras que sizebox siempre hace el trabajo.


0

Puede utilizar el contenedor, le ayudará a establecer la alineación.

Widget _buildListWidget({Map reminder}) {
return Container(
  color: Colors.amber,
  alignment: Alignment.centerLeft,
  padding: EdgeInsets.all(20),
  height: 80,
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: <Widget>[
      Container(
        alignment: Alignment.centerLeft,
        child: Text(
          reminder['title'],
          textAlign: TextAlign.left,
          style: TextStyle(
            fontSize: 16,
            color: Colors.black,
            backgroundColor: Colors.blue,
            fontWeight: FontWeight.normal,
          ),
        ),
      ),
      Container(
        alignment: Alignment.centerRight,
        child: Text(
          reminder['Date'],
          textAlign: TextAlign.right,
          style: TextStyle(
            fontSize: 12,
            color: Colors.grey,
            backgroundColor: Colors.blue,
            fontWeight: FontWeight.normal,
          ),
        ),
      ),
    ],
  ),
);
}

-1
GestureDetector(
          onTap: () {},
          child: Container(
            padding: EdgeInsets.all(5),
            color: buttonContainerColor,
            margin: EdgeInsets.only(top: 10.0),
            width: double.infinity,
            height: bottomContainerHeight,
            alignment: Alignment.center,
            child: Text(
              "CALCULATE",
              style: TextStyle(fontSize: 25.0, color: Colors.white),
            ),
          ),
        )
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.