betacode

Руководство Flutter Column

  1. Column
  2. children
  3. Add/Remove children
  4. mainAxisAlignment
  5. mainAxisSize
  6. crossAxisAlignment
  7. textDirection
  8. verticalDirection
  9. textBaseline

1. Column

Column - это виджет, который отображает свои дочерние виджеты в столбце. Другой вариант - Row, который показывает свои дочерние виджеты в строке.
Чтобы расширить дочерний виджет Column для заполнения доступного горизонтального пространства, нужно завернуть его в объект Expanded.
Column помещает своие дочерние элементы в один столбец и не может быть прокручен. Если вам нужен похожий и прокручиваемый контейнер, вам следует рассмотреть возможность использования ListView.
Column Constructor:
Column Constructor
Column(
    {Key key,
    List<Widget> children: const <Widget>[],
    MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start,
    MainAxisSize mainAxisSize: MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection: VerticalDirection.down,
    TextBaseline textBaseline
    }
)

2. children

Свойство children используется для определения списка дочерних виджетов Column.
Вы можете добавлять дочерние виджеты к children или удалять виджеты из children, но вы должны следовать правилу, упомянутому в разделе "Add/Remove Children".
List<Widget> children: const <Widget>[]
Давайте начнем с первого примера, Column с четырьмя дочерними виджетами:
main.dart (children ex1)
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Flutter Column Example")
      ),
      body: Center(
          child: Column (
              children: [
                ElevatedButton(child: Text("Button 1"), onPressed:(){}),
                Icon(Icons.ac_unit, size: 48, color: Colors.blue),
                ElevatedButton(
                    child: Text("Button 2"),
                    onPressed:(){},
                    style: ButtonStyle(
                        minimumSize: MaterialStateProperty.all(Size.square(70))
                    )
                ),
                ElevatedButton(child: Text("Very Long Button 3"), onPressed:(){}),
              ]
          )
      ),
    );
  }
}
Некоторые дочерние виджеты с flex > 0 способны расширять свою высоту для заполнения оставшегося пространства по вертикали, например Expanded, Spacer и т. д. Они часто используются для регулировки расстояния между дочерними виджетами Column. Ниже приведен пример:
children (ex2)
Column (
  children: [
    ElevatedButton(child: Text("Button 1"), onPressed:(){}),
    Expanded (
        flex: 2,
        child: Icon(Icons.ac_unit, size: 48, color: Colors.blue)
    ),
    ElevatedButton(
        child: Text("Button 2"),
        onPressed:(){},
        style: ButtonStyle(
            minimumSize: MaterialStateProperty.all(Size.square(70))
        )
    ),
    Spacer(flex: 1),
    ElevatedButton(child: Text("Very Long Button 3"), onPressed:(){}),
  ]
)

3. Add/Remove children

Вы можете добавлять несколько дочерних виджетов в Column или удалять некоторые из них из Column. Выполнение этого процесса нижеприведенным способомможет привести к неожиданным результатам:
** Not Working! **
class SomeWidgetState extends State<SomeWidget> {
  List<Widget> _children;

  void initState() {
    _children = [];
  }

  void someHandler() {
    setState(() {
        _children.add(newWidget);
    });
  }

  Widget build(BuildContext context) {
    // Reusing `List<Widget> _children` here is problematic.
    return Column(children: this._children);
  }
}
Чтобы решить вышеописанную проблему, необходимо соблюдать следующие правила:
  • Дочерним виджетам необходимо явно присвоить Key-значение, которое помогает Flutter распознавать старые или новые дочерние виджеты по мере изменения количества виджетов.
  • Новый объект List должен быть создан для Column.children, если изменяется определенный дочерний виджет или количество дочерних виджетов.
** Worked! **
class SomeWidgetState extends State<SomeWidget> {
  List<Widget> _children;

  void initState() {
    this._children = [];
  }

  // Add or remove some children..
  void someHandler() {
    setState(() {
      // The key here allows Flutter to reuse the underlying render
      // objects even if the children list is recreated.
      this._children.add(newWidget(key: ...));
    });
  }

  Widget build(BuildContext context) {
    // Always create a new list of children as a Widget is immutable.
    var newChildren = List.from(this._children);
    this._children = newChildren;
    
    return Column(children: this._children);
  }
}
Например:
main.dart (children ex3)
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return MyHomePageState();
  }
}


class MyHomePageState extends State<MyHomePage> {
  List<Widget> _children = [];
  int idx = 0;

  @override
  void initState()  {
    super.initState();

    this._children = [
      ElevatedButton(
          key: Key(this.idx.toString()),
          child: Text("Button " + idx.toString()),
          onPressed: (){}
      )
    ];
  }

  void addChildHandler()  {
    this.idx++;
    this.setState(() {
      var newChild = ElevatedButton(
          key: Key(this.idx.toString()),
          child: Text("Button " + idx.toString()),
          onPressed: (){}
      );
      this._children.add(newChild);
    });
  }

  @override
  Widget build(BuildContext context) {
    // Create new List object:

    this._children = this._children == null? [] : List.from(this._children);

    return Scaffold(
      appBar: AppBar(
          title: Text("Flutter Column Example")
      ),
      body: Center(
          child: Column (
              children:  this._children
          )
      ),
      floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: ()  {
            this.addChildHandler();
          }
      ),
    );
  }
}

4. mainAxisAlignment

Свойство mainAxisAlignment используется для указания того, как дочерние виджеты будут расположены на главной оси (main axis). Для Column, главная ось (main axis) - это вертикальная ось.
MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start
MainAxisAlignment.start
В случае verticalDirection = VerticalDirection.down (по умолчанию) и mainAxisAlignment = MainAxisAlignment.start, дочерние виджеты Column будут размещены рядом друг с другом сверху вниз.
MainAxisAlignment.start
Column (
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      ElevatedButton(child: Text("Long Button 1"), onPressed:(){}),
      ElevatedButton(
          child: Text("Button 2"),
          onPressed:(){},
          style: ButtonStyle(
              minimumSize: MaterialStateProperty.all(Size.square(70))
          )
      ),
      ElevatedButton(child: Text("Very Long Button 3"), onPressed:(){})
    ]
)
MainAxisAlignment.center
mainAxisAlignment: MainAxisAlignment.center
MainAxisAlignment.end
В случае verticalDirection = VerticalDirection.down (по умолчанию) и mainAxisAlignment = MainAxisAlignment.end, дочерние виджеты Column будут размещены рядом друг с другом снизу вверх.
mainAxisAlignment: MainAxisAlignment.end
MainAxisAlignment.spaceBetween
mainAxisAlignment: MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceEvenly
mainAxisAlignment: MainAxisAlignment.spaceEvenly
MainAxisAlignment.spaceAround
mainAxisAlignment: MainAxisAlignment.spaceAround

5. mainAxisSize

Свойство mainAxisSize указывает, какое вертикальное пространство должен занимать Column. Его значение по умолчанию - MainAxisSize. max, что означает, что Column пытается занять как можно больше вертикального пространства.
Если есть дочерний виджет с "flex > 0 && fit != FlexFit.loose", Column постарается занять как можно больше пространства независимо от значения mainAxisSize.
В противном случае, если mainAxisSize = MainAxisSize.min, Column будет иметь достаточную высоту для всех своих дочерних виджетов.
MainAxisSize mainAxisSize: MainAxisSize.max

6. crossAxisAlignment

Свойство crossAxisAlignment используется для указания того, как дочерние виджеты будут расположены на поперечной оси (cross axis). Для Column, поперечная ось (cross axis) - это горизонтальная ось.
CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center
CrossAxisAlignment.start
В случае textDirection = TextDirection.ltr (по умолчанию) и crossAxisAlignment = CrossAxisAlignment.start, дочерние виджеты Column будут размещены близко левому краю Column.
CrossAxisAlignment.center (Default).
crossAxisAlignment: CrossAxisAlignment.center
CrossAxisAlignment.end
В случае textDirection = TextDirection.ltr (по умолчанию) и crossAxisAlignment = CrossAxisAlignment.end, дочерние виджеты Column будут размещены близко к правому краю Column.
crossAxisAlignment: CrossAxisAlignment.end
CrossAxisAlignment.stretch
crossAxisAlignment: CrossAxisAlignment.stretch
CrossAxisAlignment.baseline
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic

7. textDirection

Свойство textDirection определяет, как дочерние виджеты Column будут расположены на горизонтальной оси и как слова "start" и "end" будут интерпретироваться.
TextDirection textDirection

// TextDirection enum:

TextDirection.ltr (Left to Right) (Default)
TextDirection.rtl (Right to Left)
Если textDirection = TextDirection.ltr (по умолчанию), слово "start" будет соответствовать "left", а слово "end" будет соответствовать "right".
В противном случае, при textDirection = TextDirection.rtl, слово "start" будет соответствовать "right" и слово "end" будет соответствовать "left".

8. verticalDirection

Свойство verticalDirection указывает, как дочерние виджеты Column будут расположены на главной оси (вертикальной оси) и как слова "start" и "end" будут интерпретироваться
VerticalDirection verticalDirection: VerticalDirection.down

// VerticalDirection enum:

VerticalDirection.down (Default)
VerticalDirection.up
Если verticalDirection = VerticalDirection.down (по умолчанию), слово "start"" будет соответствовать "top", а слово "end" будет соответствовать "bottom".
В противном случае, при verticalDirection = VerticalDirection.up, слово "start" будет соответствовать "bottom", а слово "end" будет соответствовать "top".

9. textBaseline

При выравнивании (align) дочерних виджетов на основе базовой линии (baseline) свойство textBaseline указывает, какой тип базовой линии будет использоваться.
TextBaseline textBaseline: TextBaseline.alphabetic

// TextBaseline enum:

TextBaseline.alphabetic  (Default)
TextBaseline.ideographic
Например:
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic

Pуководства Flutter

Show More