01-2 Row、Column、Stack、IndexedStack

[toc]

Row、Column

Row 水平方向排放子 Widget, Column 垂直方向排放 children 但不可以滚动,它们都继承自 Flex,借鉴了 web 的中的 Flex 布局。

对于 Row 来说,主轴是水平方向,横轴垂直方向。对于 Column 来说,主轴垂直方向,横轴水平方向。



mainAxisSize 用来设置 Row 或 Column 的大小。

  • MainAxisSize.max :类似 match_parent,尽可能的大
  • MainAxisSize.min :类似 wrap_content, 尽可能的小

mainAxisAlignment 和 crossAxisAlignment 两个方向上的对齐组合完成 children 的定位,start center end 分别代表左中右。

  • MainAxisAlignment.spaceEvenly :平分剩余空间
  • MainAxisAlignment.spaceAround : 平分剩余空间,但左右两边只能分到二分之一
  • MainAxisAlignment.spaceBetween :平分剩余空间,但左右两边不会分到

textDirection 可以改变 children 的布局顺序,默认 TextDirection.ltr(left to right)。

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("RowWidget"),),
        body: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,//平分剩余空间
          mainAxisSize: MainAxisSize.max,// Row 宽度最大 类似 match_parent
          crossAxisAlignment: CrossAxisAlignment.start, // y 轴对齐 top
          verticalDirection: VerticalDirection.up, // 如果 crossAxisAlignment 是 start 变为 end
          textDirection: TextDirection.rtl, // children 的排列方式  right to left
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.pinkAccent,
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.lightGreenAccent,
            ),
            Container(
              width: 50,
              height: 50,
              color: Colors.lightGreenAccent,
            ),
          ],
        ),
      ),
    );
  }

当 children 超出主轴尺寸时,Row 和 Column 会产生异常。将可以伸缩的内容放到 Expanded 中可以避免这样的异常。

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("RowWidget"),),
        body: Row(
          mainAxisSize: MainAxisSize.max,// Row 宽度最大 类似 match_parent
          crossAxisAlignment: CrossAxisAlignment.start, // y 轴对齐 top
          verticalDirection: VerticalDirection.up, // 如果 crossAxisAlignment 是 start 变为 end
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.pinkAccent,
            ),
            //两个 Expanded 分剩下的空间 Text 占 1/ 3(两个 Expanded flex 属性的和)
            Expanded(
              flex: 1,// 比例 默认 1
              child: Text("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
            ),
            Expanded(
              flex: 2,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.lightGreenAccent,
              ),
            )
          ],
        ),
      ),
    );
  }

Stack

Stack 类似 FrameLayout ,children 一层压一层。

children 分为两种:

  • positioned :Positioned Widget 包裹真正的 child ,通过 top、left 属性定位。
  • non-positioned :没有被 Positioned Widget 包裹,通过 Stack 的 alignment 定位
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stack'),
        ),
        body: Container(
          width: 300,
          height: 300,
          child: Stack(
            alignment: AlignmentDirectional.center,
            // fit 只对 non-positioned child 生效
            //loose 使用 child 自己的大小约束
            //expand 所有 child 使用 Stack 大小约束
            //passthrough  child 是 Row x轴使用 Stack 大小约束 ,y 轴使用自己的大小约束
            fit: StackFit.loose,
            overflow: Overflow.visible, // 高度 1000 的 Container 并没有可见,不知道有啥子用
            children: [
              Container(
                width: 200,
                height: 200,
                color: Colors.lightGreenAccent,
              ),
              Container(
                width: 100,
                height: 1000,
                color: Colors.redAccent,
              ),
              Positioned(
                left: 80,
                top: 20,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.pinkAccent,
                ),
              ),
              Row(
                // Row 默认 children 对齐是 start , Stack 的 fit 改成 passthrough 观察 Text 位置
                mainAxisSize: MainAxisSize.min,
                children: [
                    Text('AAA'),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }

IndexedStack

IndexedStack 每次只显示 Stack 中 index 指定的一层,index 默认为 0。

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stack'),
        ),
        body: Container(
          width: 300,
          height: 300,
          child: IndexedStack(
            alignment: AlignmentDirectional.center,
            //显示 child 索引,默认值为 0
            index: 1,
            children: [
              Container(
                width: 200,
                height: 200,
                color: Colors.lightGreenAccent,
              ),
              Container(
                width: 100,
                height: 1000,
                color: Colors.redAccent,
              ),
            ],
          ),
        ),
      ),
    );
  }

你可能感兴趣的:(01-2 Row、Column、Stack、IndexedStack)