[flutter-19] Layout (多布局)

1. Layout (多布局)

多布局组件常见的有:

  • Row
  • Column
  • Stack

在使用过程中,也搭配学习:

  • Expand(扩张组件)
  • Positioned(只在Stack中使用)

1.1 Flex 组件

  • 我们即将学习的Row、Column组件都是继承自Alex组件
  • Flex组件和Row、Column的区别就是多了一个direction
  • 当direction = Axis.horizontal, 则为Row
  • 当direction = Axis.vertical,则为Column

在学习Row 和 Column 之前,我们学习一下主轴 和 交叉轴的区别

  • Row来说,主轴 & 交叉轴
    [flutter-19] Layout (多布局)

  • Column来说, 主轴 & 交叉轴
    [flutter-19] Layout (多布局)

1.2 Row 一行

Row({
  Key key,
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主轴对齐方式
  MainAxisSize mainAxisSize = MainAxisSize.max, // 水平方向尽可能大, 默认就是max
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 交叉处对齐方式
  TextDirection textDirection, // 水平方向子widget的布局顺序(默认为系统当前Locale环境的文本方向(如中文、英语都是从左往右,而阿拉伯语是从右往左))
  VerticalDirection verticalDirection = VerticalDirection.down, // 表示Row纵轴(垂直)的对齐方向
  TextBaseline textBaseline, // 如果上面是baseline对齐方式,那么选择什么模式(有两种可选)
  List<Widget> children = const <Widget>[],
})

/*
mainAxisSize:
表示Row在主轴(水平)方向占用的空间,默认是MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度
而MainAxisSize.min表示尽可能少的占用水平空间,当子widgets没有占满水平剩余空间,则Row的实际宽度等于所有子widgets占用的的水平空间;

mainAxisAlignment:表示子Widgets在Row所占用的水平空间内对齐方式
如果mainAxisSize值为MainAxisSize.min,则此属性无意义,因为子widgets的宽度等于Row的宽度
如果mainAxisSize值为MainAxisSize.min,则此属性无意义,因为子widgets的宽度等于Row的宽度
MainAxisAlignment.start表示沿textDirection的初始方向对齐,
如textDirection取值为TextDirection.ltr时,则MainAxisAlignment.start表示左对齐,textDirection取值为TextDirection.rtl时表示从右对齐。
而MainAxisAlignment.end和MainAxisAlignment.start正好相反;
MainAxisAlignment.center表示居中对齐。

crossAxisAlignment:表示子Widgets在纵轴方向的对齐方式

主轴
enum MainAxisAlignment {
  start, // 所有视图向左边靠齐
  end, // 所有视图向右边靠齐
  center, // 中间紧挨着间距为0,两边一样大
  spaceBetween, // 最外面两边间距为0、中间均匀
  spaceAround, // 最外面两边间距小于中间均匀的间距
  spaceEvenly, // 间距均匀
}

// 纵横轴
enum CrossAxisAlignment {
  start, // 顶部靠齐
  end, // 底部靠齐
  center, // 中间平衡
  stretch, // 填充
  baseline, // 也是顶部靠齐
}

*/

1.2.1 RowDemo

class RowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      crossAxisAlignment: CrossAxisAlignment.end,
      children: [
        Expanded(
          flex: 1,
          child: Container(color: Colors.red, height: 60),
        ),
        Container(color: Colors.blue, width: 80, height: 90),
        Container(color: Colors.green, width: 70, height: 70),
        Expanded(
          // 扩张Widget
          flex: 3, // 弹性系数
          child: Container(color: Colors.orange, height: 100),
        ),
      ],
    );
  }
}

[flutter-19] Layout (多布局)

1.3 Expanded 扩张填充组件

  • 如果想要水平方向填充、则无需设置宽度、只需要设置高度即可,根据弹性系数来进行比例宽度填充
  • flex属性,弹性系数,Row会根据两个Expanded的弹性系数来决定它们占据剩下空间的比例

1.4 Column 一列

Column({
    Key key,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
  })

1.4.1 ColumnDemo

class ColumnDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 主轴 均匀间距对齐
      crossAxisAlignment: CrossAxisAlignment.start, // 交叉轴 起始位置对齐
      children: [
        // Expanded(
        //   flex: 1,
        //   child: Container(color: Colors.red, width: 60),
        // ),
        Container(color: Colors.blue, width: 80, height: 90),
        Container(color: Colors.green, width: 70, height: 70),
        Container(color: Colors.orange, width: 100, height: 100),
        // Expanded(
        //   // 扩张Widget
        //   flex: 1, // 弹性系数
        //   child: Container(color: Colors.orange, width: 100),
        // ),
      ],
    );
  }
}

[flutter-19] Layout (多布局)

1.5 Stack 层叠组件

  • 如果需要底部是一个Container、然后在这个Container上面放很多Widget、则可以使用Stack组件
  • Positioned组件只能使用在Stack里、主要是为了指定widgte在具体哪个位置
Stack({
  Key key,
  this.alignment = AlignmentDirectional.topStart, // 对齐方式
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})

/*
fit:此参数用于决定没有定位的子widget如何去适应Stack的大小。StackFit.loose表示使用子widget的大小,StackFit.expand表示扩伸到Stack的大小。
overflow:此属性决定如何显示超出Stack显示空间的子widget,值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible 时则不会

*/

1.5.1 StackDemo

//**注意:**Positioned组件只能在Stack中使用。
class StackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          color: Colors.green,
          width: MediaQuery.of(context).size.width,
          height: 500,
        ),
        Positioned(
          left: 30,
          top: 30,
          child: Icon(Icons.favorite, size: 50, color: Colors.red),
        ),
        Positioned(right: 20, bottom: 20, child: Text('此致 \n      敬礼')),
      ],
    );
  }
}

[flutter-19] Layout (多布局)

上一篇:javascript高级程序设计(六)集合类型引用


下一篇:R绘图体系ggplot2 基础篇:颜色搭配 (纠结症稳定剂)