betacode

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

View more Tutorials:

Сайт бесплатного изучения языков:
Следуйте за нами на нашей фан-странице, чтобы получать уведомления каждый раз, когда появляются новые статьи. Facebook

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);
  }
}
Чтобы решить вышеописанную проблему, необходимо соблюдать следующие правила:
  1. Дочерним виджетам необходимо явно присвоить Key-значение, которое помогает Flutter распознавать старые или новые дочерние виджеты по мере изменения количества виджетов.
  2. Новый объект 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.minColumn будет иметь достаточную высоту для всех своих дочерних виджетов.

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

View more Tutorials: