¿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.

Atenúa
fuente
¿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.

Rémi Rousselet
fuente
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

El verdadero yo
fuente
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í

CopsOnRoad
fuente
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(""),
    ]);
Navin Kumar
fuente
3

Colocado alignment: Alignment.centerRighten contenedor:

Container(
    alignment: Alignment.centerRight,
    child:Text(
       "Hello",
    ),
)
Lay Leangsros
fuente
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.

Tommy95
fuente
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,
          ),
        ),
      ),
    ],
  ),
);
}
Anit Kumar
fuente
-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),
            ),
          ),
        )
Ufuk Zimmerman
fuente