Flutter常用组件系列总结-Column组件布局篇五

Column组件即垂直布局控件,能够将子组件垂直排列。其实你学会了Row组件就基本掌握了Column组件,你可打开Row()组件的构造函数对比一下,它们的参数完全是一模一样的,只是排列方向不同,下面一起探究Column布局吧。

来看一下Column()组件的源码定义:

/// ## Layout algorithm
///
/// _This section describes how a [Column] is rendered by the framework._
/// _See [BoxConstraints] for an introduction to box layout models._
///
/// Layout for a [Column] proceeds in six steps:
///
/// 1. Layout each child a null or zero flex factor (e.g., those that are not
///    [Expanded]) with unbounded vertical constraints and the incoming
///    horizontal constraints. If the [crossAxisAlignment] is
///    [CrossAxisAlignment.stretch], instead use tight horizontal constraints
///    that match the incoming max width.
/// 2. Divide the remaining vertical space among the children with non-zero
///    flex factors (e.g., those that are [Expanded]) according to their flex
///    factor. For example, a child with a flex factor of 2.0 will receive twice
///    the amount of vertical space as a child with a flex factor of 1.0.
/// 3. Layout each of the remaining children with the same horizontal
///    constraints as in step 1, but instead of using unbounded vertical
///    constraints, use vertical constraints based on the amount of space
///    allocated in step 2. Children with [Flexible.fit] properties that are
///    [FlexFit.tight] are given tight constraints (i.e., forced to fill the
///    allocated space), and children with [Flexible.fit] properties that are
///    [FlexFit.loose] are given loose constraints (i.e., not forced to fill the
///    allocated space).
/// 4. The width of the [Column] is the maximum width of the children (which
///    will always satisfy the incoming horizontal constraints).
/// 5. The height of the [Column] is determined by the [mainAxisSize] property.
///    If the [mainAxisSize] property is [MainAxisSize.max], then the height of
///    the [Column] is the max height of the incoming constraints. If the
///    [mainAxisSize] property is [MainAxisSize.min], then the height of the
///    [Column] is the sum of heights of the children (subject to the incoming
///    constraints).
/// 6. Determine the position for each child according to the
///    [mainAxisAlignment] and the [crossAxisAlignment]. For example, if the
///    [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], any vertical
///    space that has not been allocated to children is divided evenly and
///    placed between the children.
///
/// See also:
///
///  * [Row], for a horizontal equivalent.
///  * [Flex], if you don't know in advance if you want a horizontal or vertical
///    arrangement.
///  * [Expanded], to indicate children that should take all the remaining room.
///  * [Flexible], to indicate children that should share the remaining room but
///    that may size smaller (leaving some remaining room unused).
///  * [SingleChildScrollView], whose documentation discusses some ways to
///    use a [Column] inside a scrolling container.
///  * [Spacer], a widget that takes up space proportional to its flex value.
///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
class Column extends Flex {
  /// Creates a vertical array of children.
  ///
  /// The [direction], [mainAxisAlignment], [mainAxisSize],
  /// [crossAxisAlignment], and [verticalDirection] arguments must not be null.
  /// If [crossAxisAlignment] is [CrossAxisAlignment.baseline], then
  /// [textBaseline] must not be null.
  ///
  /// The [textDirection] argument defaults to the ambient [Directionality], if
  /// any. If there is no ambient directionality, and a text direction is going
  /// to be necessary to disambiguate `start` or `end` values for the
  /// [crossAxisAlignment], the [textDirection] must not be null.
  Column({
    Key key,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, //Clomun组件的主轴默认对齐布局方式
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//Clomun组件的交叉轴默认对齐布局方式
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
  }) : super(
    children: children,
    key: key,
    direction: Axis.vertical,
    mainAxisAlignment: mainAxisAlignment,
    mainAxisSize: mainAxisSize,
    crossAxisAlignment: crossAxisAlignment,
    textDirection: textDirection,
    verticalDirection: verticalDirection,
    textBaseline: textBaseline,
  );
}

   属性名即作用:

    mainAxisAlignment: 主轴的排列方式,也是Column()组件布局的主轴布局方式
    mainAxisSize: 主轴应该占据多少空间,取值max为最大值,取值min为最小值。
    crossAxisAlignment: 次轴的排列方式,也是Column()组件布局的次轴布局方式

上面的官方英文介绍和Row()组件很像,这里就不再翻译。可以看出Column()组件也有主轴和交叉轴(副轴、次轴都是指的交叉轴),只不过Column()组件的主轴方向是竖直方向了,如图:

这时在回过头看Row()组件的主轴、交叉轴方向是什么样的,可以对比下。

网上很多的总结:

Row()组件的主轴:孩子组件排列的方向是水平方向,所以主轴是水平方向,交叉轴与主轴垂直。

Column()组件的主轴:孩子组件排列的方向是竖直方向,所以主轴是竖直方向,交叉轴与主轴垂直。

布局的对齐方式

    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center

对齐方式的枚举类:

enum MainAxisAlignment {
  /// Place the children as close to the start of the main axis as possible.
  ///
  /// If this value is used in a horizontal direction, a [TextDirection] must be
  /// available to determine if the start is the left or the right.
  ///
  /// If this value is used in a vertical direction, a [VerticalDirection] must be
  /// available to determine if the start is the top or the bottom.
  start,

  /// Place the children as close to the end of the main axis as possible.
  ///
  /// If this value is used in a horizontal direction, a [TextDirection] must be
  /// available to determine if the end is the left or the right.
  ///
  /// If this value is used in a vertical direction, a [VerticalDirection] must be
  /// available to determine if the end is the top or the bottom.
  end,

  /// Place the children as close to the middle of the main axis as possible.
  center,

  /// Place the free space evenly between the children.
  spaceBetween,

  /// Place the free space evenly between the children as well as half of that
  /// space before and after the first and last child.
  spaceAround,

  /// Place the free space evenly between the children as well as before and
  /// after the first and last child.
  spaceEvenly,
}

/// How the children should be placed along the cross axis in a flex layout.
///
/// See also:
///
///  * [Column], [Row], and [Flex], the flex widgets.
///  * [RenderFlex], the flex render object.
enum CrossAxisAlignment {
  /// Place the children with their start edge aligned with the start side of
  /// the cross axis.
  ///
  /// For example, in a column (a flex with a vertical axis) whose
  /// [TextDirection] is [TextDirection.ltr], this aligns the left edge of the
  /// children along the left edge of the column.
  ///
  /// If this value is used in a horizontal direction, a [TextDirection] must be
  /// available to determine if the start is the left or the right.
  ///
  /// If this value is used in a vertical direction, a [VerticalDirection] must be
  /// available to determine if the start is the top or the bottom.
  start,

  /// Place the children as close to the end of the cross axis as possible.
  ///
  /// For example, in a column (a flex with a vertical axis) whose
  /// [TextDirection] is [TextDirection.ltr], this aligns the right edge of the
  /// children along the right edge of the column.
  ///
  /// If this value is used in a horizontal direction, a [TextDirection] must be
  /// available to determine if the end is the left or the right.
  ///
  /// If this value is used in a vertical direction, a [VerticalDirection] must be
  /// available to determine if the end is the top or the bottom.
  end,

  /// Place the children so that their centers align with the middle of the
  /// cross axis.
  ///
  /// This is the default cross-axis alignment.
  center,

  /// Require the children to fill the cross axis.
  ///
  /// This causes the constraints passed to the children to be tight in the
  /// cross axis.
  stretch,

  /// Place the children along the cross axis such that their baselines match.
  ///
  /// If the main axis is vertical, then this value is treated like [start]
  /// (since baselines are always horizontal).
  baseline,
}

对齐方式和Row()组件的枚举类一样,不再累述!

灵活与非灵活布局

同样Column()组件的布局方式,其孩子组件也是分灵活布局和非灵活布局,即是否使用Expanded()组件包裹。同样也有 "flex factor" [伸缩因子] 的属性设置。

下面直接给出几个使用示例:

非灵活Column()布局:

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title:Text('优品酒家')),
      body:Container(
        child: Column(
          children:[
            Container(
              child:new RaisedButton(
                  onPressed: (){
                  },
                  color:Colors.redAccent,
                  child:new Text('红色按钮')
              ),
              width: 100.0,
              height: 150.0,
            ),
            Container(
              child:new RaisedButton(
                onPressed: (){
                },
                color:Colors.orangeAccent,
                child: new Text('黄色按钮'),
              ),
              width: 100.0,
              height: 150.0,
            ),
            Container(
              child: new RaisedButton(
                  onPressed: (){
                  },
                  color:Colors.pinkAccent,
                  child:new Text('粉色按钮')
              ),
              width: 100.0,
              height: 150.0,
            )
          ]
        ),
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
      )
    );
  }
}

代码运行效果图,可以看出Column()组件主轴默认的对齐方式是start,而交叉轴默认的排列方式是center,在上面的构造方法中也能体现:

设置灵活的Column()组件布局,并且主轴的排列方式为center,交叉轴的排列方式为start,代码如下:

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title:Text('优品酒家')),
      body:Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,//灵活布局主轴方向上看不出来了
          crossAxisAlignment: CrossAxisAlignment.start,
          children:[
            Expanded(
                child: Container(
                  child:new RaisedButton(
                      onPressed: (){
                      },
                      color:Colors.redAccent,
                      child:new Text('红色按钮')
                  ),
                  width: 100.0,
                  height: 150.0,
                )
            ),
            Expanded(
                child: Container(
                  child:new RaisedButton(
                    onPressed: (){
                    },
                    color:Colors.orangeAccent,
                    child: new Text('黄色按钮'),
                  ),
                  width: 100.0,
                  height: 150.0,
                )
            ),
            Expanded(
                child: Container(
                  child: new RaisedButton(
                      onPressed: (){
                      },
                      color:Colors.pinkAccent,
                      child:new Text('粉色按钮')
                  ),
                  width: 100.0,
                  height: 150.0,
                )
            )
          ]
        ),
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
      )
    );
  }
}

 代码运行的效果图如下:

对于伸缩因子flex属性示例如下:

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title:Text('优品酒家')),
      body:Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children:[
            Expanded(
                flex: 2,
                child: Container(
                  child:new RaisedButton(
                      onPressed: (){
                      },
                      color:Colors.redAccent,
                      child:new Text('红色按钮 flex: 2')
                  ),
                  width: 100.0,
                )
            ),
            Expanded(
                flex: 1,
                child: Container(
                  child:new RaisedButton(
                    onPressed: (){
                    },
                    color:Colors.orangeAccent,
                    child: new Text('黄色按钮 flex: 1'),
                  ),
                  width: 100.0,
                )
            ),
            Container(
              child: new RaisedButton(
                  onPressed: (){
                  },
                  color:Colors.pinkAccent,
                  child:new Text('粉色按钮')
              ),
              width: 100.0,
              height: 150.0,
            )
          ]
        ),
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
      )
    );
  }
}

代码运行效果如下:

好了,Column()组件布局总结就到这里!

遇见即使缘分,感谢每一位爱进步的小伙伴的不吝时间阅读。岁月如潺潺泉水般流淌,唯有学习与强大自我,才不负韶华!

下一篇总结:Flutter常用组件系列总结- Stack()组件层叠布局(六) https://mp.csdn.net/editor/html/110289561

原文地址:https://blog.csdn.net/luqingshuai_eloong/article/details/110284737

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


简介 java中使用jar包来封装有用的功能,然后将其分发到maven仓库中,供其他人使用。同样的在dart中也有类似的概念叫做packages。packages就是可以用来共享的软件包,可以包含libraries和tools。 你可以在pub.dev网站中查到dart中所有的共享packages的
简介 flutter是google在2015年dart开发者峰会上推出的一种开源的移动UI构建框架,使用flutter可以非常方便的编译成运行在原始android,ios,web等移动平台上的移动应用。 flutter是使用dart来编写的,最新的flutter版本是2.5.3,而最新的Dart语言
简介 dart作为一种面向对象的语言,class是必不可少的。dart中所有的class,除了Null都继承自Object class。 要想使用dart中的类就要构造类的实例,在dart中,一个类的构造函数有两种方式,一起来看看吧。 传统的构造函数 和JAVA一样,dart中可以使用和class名
简介 Exception是程序中的异常情况,在JAVA中exception有checked Exception和unchecked Exception。那么在dart中的情况是不是一样的呢?一起来看看吧。 Exception和Error Dart中表示异常的类有两个,分别是Exception和Err
简介 虽然dart中的类只能有一个父类,也就是单继承的,但是dart提供了mixin语法来绕过这样限制。 今天,和大家一起来探讨一下dart类中的继承。 使用extends 和JAVA一样,dart中可以定义一个父类,然后使用extends来继承他,得到一个子类,如下所示: class Studen
简介 pubspec.yaml是所有dart项目的灵魂,它包含了所有dart项目的依赖信息和其他元信息,所以pubspec.yaml就是dart项目的meta! pubspec.yaml支持的字段 根据dart的定义,pubspec.yaml中可以包含下面的字段: 字段名 是否必须字段 描述 nam
dart系列之:dart语言中的特殊操作符 简介 有运算就有操作符,dart中除了普通的算术运算的操作符之外,还有自定义的非常特殊的操作符,今天带大家一起来探索一下dart中的特殊操作符。 普通操作符 普通操作符就很好解释了,就是加减乘除,逻辑运算符,比较运算符和位运算符等。 这些操作符和其他语言的
简介 在dart系统中,有pubspec.yaml文件的应用就可以被成为一个package。而Libray package是一类特殊的package,这种包可以被其他的项目所依赖. 也就是通常所说的库。 如果你也想你写的dart程序可以上传到pub.dev上,或者提供给别人使用,则来看看这篇文章吧。
简介 和所有的编程语言一样,dart有他内置的语言类型,这些内置类型都继承自Object,当然这些内置类型是dart语言的基础,只有掌握了这些内置类型才能够在使用dart语言的时候得心应手。 今天就给大家讲解一下dart语言的内置类型。 Null 在dart中用null来表示空。那么null和Nul
简介 函数是所有编程语言都有的内容,不管是面向对象还是面向过程,函数都是非常重要的一部分。dart中的函数和java中的函数有什么区别呢? dart作为一种面向对象的编程语言,它的函数也是一个对象,用Function来表示。先看下函数的定义: abstract class Function { ex
简介 熟悉JAVA的朋友可能知道,JAVA在8中引入了泛型的概念。什么是泛型呢?泛型就是一种通用的类型格式,一般用在集合中,用来指定该集合中应该存储的对象格式。 有了泛型可以简化我们的编程,并且可以减少错误的产生,非常的方便。 dart语言中也有泛型。一起来看看吧。 为什么要用泛型 使用泛型的主要目
简介 熟悉javascript的朋友应该知道,在ES6中引入了await和async的语法,可以方便的进行异步编程,从而摆脱了回调地狱。dart作为一种新生的语言,没有理由不继承这种优秀的品质。很自然的,dart中也有await和async语言,一起来看看吧。 为什么要用异步编程 那么为什么要用异步
简介 要想熟悉一种语言,最简单的做法就是熟悉dart提供的各种核心库。dart为我们提供了包括dart:core,dart:async,dart:math,dart:convert,dart:html和dart:io这几种常用的库。 今天给大家介绍一下dart:core中的数字和字符串的使用。 数字
简介 ES6中在引入异步编程的同时,也引入了Generators,通过yield关键词来生成对应的数据。同样的dart也有yield关键词和生成器的概念。 什么时候生成器呢?所谓生成器就是一个能够持续产生某些数据的装置,也叫做generator。 两种返回类型的generator 根据是同步生成还是
简介 Flutter的基础是widget,根据是否需要跟用户进行交互,widget则可以分为StatelessWidget和StatefulWidget。StatelessWidget只能根据传入的状态进行简单的初始化widget,如果要实现跟用户交互这种复杂的功能,则需要用到StatefulWid
简介 时间和日期是我们经常会在程序中使用到的对象。但是对时间和日期的处理因为有不同时区的原因,所以一直以来都不是很好用。就像在java中,为时间和日期修改和新增了多次API,那么作为新生的语言dart而言,会有什么不一样的地方吗? dart中关于日期和时间的两个非常重要的类是DateTime和Dur
简介 Library是dart用来组织代码的一种非常有用的方式,通过定义不同的Library,可以将非常有用的dart代码进行封装,从而提供给其他的项目使用。虽然我们可以自由使用import或者export来对library进行导入和导入。但是什么样的用法才是最合适的用法呢? 一起来看看吧。 使用p
简介 dart中的集合有三个,分别是list,set和map。dart在dart:core包中提供了对于这三种集合非常有用的方法,一起来看看吧。 List的使用 首先是list的创建,可以创建空的list或者带值的list: var emptyList =[]; var nameList = [&#
简介 dart:html包为dart提供了构建浏览器客户端的一些必须的组件,之前我们提到了HTML和DOM的操作,除了这些之外,我们在浏览器端另一个常用的操作就是使用XMLHttpRequest去做异步HTTP资源的请求,也就是AJAX请求。 dart同样提供了类似JS中XMLHttpRequest
简介 Flutter是google开发的一个跨平台的UI构建工具,flutter目前最新的版本是3.0.5。使用flutter你可以使用一套代码搭建android,IOS,web和desktop等不同平台的应用。做到一次编写到处运行的目的。 说到一次编写处处运行,大家可能会想到java。那么flut