В каких обстоятельствах свойство TextAlign работает во Flutter?

В приведенном ниже textAlign свойство textAlign не работает. Если вы удалите упаковщик DefaultTextStyle которая на несколько уровней выше, textAlign начнет работать.

Почему и как обеспечить его постоянную работу?

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,)
      ],))
    );
  }
}

Оба подхода, предложенные Реми, очевидно, не работают "в дикой природе". Вот пример, который я вложил как в строки, так и в столбцы. Первый подход не выполняет выравнивание, а второй подход приводит к сбою приложения:

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)),
                ],)),
              ],)*/]
    )));
  }
}

Что я получаю из кода

enter image description here

т.е. текст центрирован, игнорируя выравнивание элемента Align.

Ответ 1

DefaultTextStyle не имеет отношения к проблеме. Для его удаления просто используется стиль по умолчанию, который намного больше того, который вы использовали, поэтому он скрывает проблему.


textAlign выравнивает текст в пространстве, занимаемом Text, когда это занимаемое пространство больше, чем фактическое содержимое.

Дело в том, что внутри Column ваш Text занимает минимум места. Именно тогда Column выравнивает своих потомков, используя crossAxisAlignment, по умолчанию center.

Простой способ уловить такое поведение - обернуть ваши тексты так:

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

Который, используя предоставленный вами код, выдает следующее:

enter image description here

Проблема внезапно становится очевидной: Text не берет всю ширину Column.


Теперь у вас есть несколько решений.

Вы можете заключить свой Text в Align, чтобы имитировать поведение textAlign

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

Что сделает следующее:

enter image description here

или вы можете заставить свой Text заполнить ширину Column.

Либо указав crossAxisAlignment: CrossAxisAlignment.stretch в Column, либо используя SizedBox с бесконечным width.

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

который отображает следующее:

enter image description here

В этом примере это TextAlign, который поместил текст слева.

Ответ 2

Укажите crossAxisAlignment: CrossAxisAlignment.start в вашем столбце

Ответ 3

Свойство textAlign работает только тогда, когда для содержимого Text остается больше места. Ниже приведены 2 примера, которые показывают, когда textAlign оказывает влияние, а когда нет.


Не влияет

Например, в этом примере это не окажет никакого влияния, потому что нет дополнительного места для содержимого Text.

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

enter image description here


Оказывает влияние

Если вы оберните его в Container и предоставите дополнительный width, чтобы в нем было больше свободного места.

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

enter image description here