devstory

Le Tutoriel de 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 est un widget qui affiche ses widgets enfants sur une colonne. Une autre variante est Row qui montre ses widgets enfants sur une ligne.
Pour qu'un widget enfant de Column s'ouvre pour remplir l'espace vertical disponible, vous pouvez l'envelopper dans un objet Expanded.
Column place ses enfants sur une colonne et ne peut pas faire se défiler. Si vous souhaitez obtenir un conteneur similaire et défilable, vous pouvez utiliser 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

La propriété children est utilisée pour définir une liste de widgets enfants de Column.
Vous pouvez ajouter des widgets enfants à children ou supprimer des widgets de children, mais vous devez suivre la règle mentionnée dans la section "Add/Remove Children".
List<Widget> children: const <Widget>[]
À commencer par le premier exemple, une Column avec quatre widgets enfants:
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:(){}),
              ]
          )
      ),
    );
  }
}
Certains widgets enfants avec flex> 0 sont capables d'étendre sa hauteur pour remplir l'espace restant verticalement comme Expanded et Spacer, etc. Ils sont souvent utilisés pour ajuster la distance entre les widgets enfants de Column. Ci-dessous un exemple:
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

Vous pouvez ajouter quelques widgets enfants à une Column ou en supprimer certains de Column. Suivre l'instruction ci-dessous pour obtenir des résultats inattendus:
** 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);
  }
}
Pour résoudre le problème ci-dessus, vous devez respecter les règles suivantes:
  • Une valeur Key doit être explicitement attribuée aux widgets enfants, ce qui permet à Flutter de reconnaître les anciens ou les nouveaux widgets enfants lorsque le nombre de widgets enfants change.
  • Un nouvel objet List doit être créé pour Column.children si un certain widget enfant change, ou le nombre de widgets enfants change.
** 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);
  }
}
Par exemple:
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

La propriété mainAxisAlignment est utilisée pour spécifier la manière dont les widgets enfants seront organisés sur l'axe principal. Quant à Column, l'axe principal est l'axe vertical principal.
MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start
MainAxisAlignment.start
Au cas où verticalDirection = VerticalDirection.down (par défaut) et mainAxisAlignment = MainAxisAlignment.start, les widgets enfants de Column seront placés côte à côte de haut en bas.
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
Si Vertical Direction = Vertical Direction.down (par défaut) et mainAxisAlignment = MainAxisAlignment.end, les widgets enfants de Column seront placés côte à côte de bas en haut.
mainAxisAlignment: MainAxisAlignment.end
MainAxisAlignment.spaceBetween
mainAxisAlignment: MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceEvenly
mainAxisAlignment: MainAxisAlignment.spaceEvenly
MainAxisAlignment.spaceAround
mainAxisAlignment: MainAxisAlignment.spaceAround

5. mainAxisSize

La propriété mainAxisSize spécifie la quantité d'espace vertical devant être occupée par Column. Sa valeur par défaut est MainAxisSize.max, ce qui signifie que Column essaie d'occuper le plus d'espace vertical que possible.
S'il y a un widget enfant avec "flex> 0 && fit! = FlexFit.loose", Column essaiera de prendre autant d'espace que possible quelle que soit la valeur de mainAxisSize.
À l'inverse, si mainAxisSize = MainAxisSize.min, Column aura une hauteur suffisante pour tous ses widgets enfants.
MainAxisSize mainAxisSize: MainAxisSize.max

6. crossAxisAlignment

La propriété crossAxisAlignment est utilisée pour spécifier la manière dont les widgets enfants seront disposés sur l'axe transversal. Comme pour Column,l'axe transversal est l'axe horizontal.
CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center
CrossAxisAlignment.start
Au cas où textDirection = TextDirection.ltr (par défaut) et crossAxisAlignment = CrossAxisAlignment.start, les widgets enfants de Column seront placés près de son bord gauche.
CrossAxisAlignment.center (Default).
crossAxisAlignment: CrossAxisAlignment.center
CrossAxisAlignment.end
Au cas où textDirection = TextDirection.ltr (par défaut) et crossAxisAlignment = CrossAxisAlignment.end, les widgets enfants de Column seront placés près du bord droit de la Column.
crossAxisAlignment: CrossAxisAlignment.end
CrossAxisAlignment.stretch
crossAxisAlignment: CrossAxisAlignment.stretch
CrossAxisAlignment.baseline
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic

7. textDirection

La propriété textDirection spécifie la manière dont les widgets enfants de Column seront disposés sur l'axe horizontal et celle dont les mots "start" et "end" sont interprétés.
TextDirection textDirection

// TextDirection enum:

TextDirection.ltr (Left to Right) (Default)
TextDirection.rtl (Right to Left)
Si textDirection = TextDirection.ltr (par défaut), le mot "start" correspondra à "left" et le mot "end" correspondra à "right".
En revanche, au cas où textDirection = TextDirection.rtl, le mot "start" correspondra à "right" et le mot "end" correspondra à "left".

8. verticalDirection

La propriété verticalDirection spécifie la manière dont les widgets enfants de Column seront disposés sur l'axe principal (axe vertical) et celle dont les mots "start" et "end" sont interprétés.
VerticalDirection verticalDirection: VerticalDirection.down

// VerticalDirection enum:

VerticalDirection.down (Default)
VerticalDirection.up
Si verticalDirection = VerticalDirection.down (par défaut), le mot "start" correspondra à "top" et le mot "end" correspondra à "bottom".
À l'inverse, si verticalDirection = VerticalDirection.up, le mot "start" correspondra à "bottom" et le mot "end" correspondra à "top".

9. textBaseline

Si vous alignez les widgets enfants en fonction de la ligne de base (baseline), la propriété textBaseline spécifie le type de ligne de base sera utilisé.
TextBaseline textBaseline: TextBaseline.alphabetic

// TextBaseline enum:

TextBaseline.alphabetic  (Default)
TextBaseline.ideographic
Par exemple:
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic

Tutoriels de programmation Flutter

Show More