微信交流群

老孟公众号

# 叠加布局组件

叠加布局组件包含 StackIndexedStack,Stack 组件将子组件叠加显示,根据子组件的顺利依次向上叠加,用法如下:

Stack(
  children: <Widget>[
    Container(
      height: 200,
      width: 200,
      color: Colors.red,
    ),
    Container(
      height: 170,
      width: 170,
      color: Colors.blue,
    ),
    Container(
      height: 140,
      width: 140,
      color: Colors.yellow,
    )
  ],
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Stack 对未定位(不被 Positioned 包裹)子组件的大小由 fit 参数决定,默认值是 StackFit.loose ,表示子组件自己决定,StackFit.expand 表示尽可能的大,用法如下:

Stack(
  fit: StackFit.expand,
  children: <Widget>[
    Container(
      height: 200,
      width: 200,
      color: Colors.red,
    ),
    Container(
      height: 170,
      width: 170,
      color: Colors.blue,
    ),
    Container(
      height: 140,
      width: 140,
      color: Colors.yellow,
    )
  ],
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

效果只有黄色(最后一个组件的颜色),并不是其他组件没有绘制,而是另外两个组件被黄色组件覆盖。

Stack 对未定位(不被 Positioned 包裹)子组件的对齐方式由 alignment 控制,默认左上角对齐,用法如下:

Stack(
  alignment: AlignmentDirectional.center,
  children: <Widget>[
    Container(
      height: 200,
      width: 200,
      color: Colors.red,
    ),
    Container(
      height: 170,
      width: 170,
      color: Colors.blue,
    ),
    Container(
      height: 140,
      width: 140,
      color: Colors.yellow,
    )
  ],
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

通过 Positioned 定位的子组件:

Stack(
  alignment: AlignmentDirectional.center,
  children: <Widget>[
    Container(
      height: 200,
      width: 200,
      color: Colors.red,
    ),
    Container(
      height: 170,
      width: 170,
      color: Colors.blue,
    ),
    Positioned(
      left: 30,
      right: 40,
      bottom: 50,
      top: 60,
      child: Container(
        color: Colors.yellow,
      ),
    )
  ],
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

topbottomleftright 四种定位属性,分别表示距离上下左右的距离。

如果子组件超过 Stack 边界由 overflow 控制,默认是裁剪,下面设置总是显示的用法:

Stack(
  overflow: Overflow.visible,
  children: <Widget>[
    Container(
      height: 200,
      width: 200,
      color: Colors.red,
    ),
    Positioned(
      left: 100,
      top: 100,
      height: 150,
      width: 150,
      child: Container(
        color: Colors.green,
      ),
    )
  ],
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

IndexedStack 是 Stack 的子类,Stack 是将所有的子组件叠加显示,而 IndexedStack 通过 index 只显示指定索引的子组件,用法如下:

class IndexedStackDemo extends StatefulWidget {
  
  _IndexedStackDemoState createState() => _IndexedStackDemoState();
}

class _IndexedStackDemoState extends State<IndexedStackDemo> {
  int _index = 0;

  
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        SizedBox(height: 50,),
        _buildIndexedStack(),
        SizedBox(height: 30,),
        _buildRow(),
      ],
    );
  }

  _buildIndexedStack() {
    return IndexedStack(
      index: _index,
      children: <Widget>[
        Center(
          child: Container(
            height: 300,
            width: 300,
            color: Colors.red,
            alignment: Alignment.center,
            child: Icon(
              Icons.fastfood,
              size: 60,
              color: Colors.blue,
            ),
          ),
        ),
        Center(
          child: Container(
            height: 300,
            width: 300,
            color: Colors.green,
            alignment: Alignment.center,
            child: Icon(
              Icons.cake,
              size: 60,
              color: Colors.blue,
            ),
          ),
        ),
        Center(
          child: Container(
            height: 300,
            width: 300,
            color: Colors.yellow,
            alignment: Alignment.center,
            child: Icon(
              Icons.local_cafe,
              size: 60,
              color: Colors.blue,
            ),
          ),
        ),
      ],
    );
  }

  _buildRow() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        IconButton(
          icon: Icon(Icons.fastfood),
          onPressed: () {
            setState(() {
              _index = 0;
            });
          },
        ),
        IconButton(
          icon: Icon(Icons.cake),
          onPressed: () {
            setState(() {
              _index = 1;
            });
          },
        ),
        IconButton(
          icon: Icon(Icons.local_cafe),
          onPressed: () {
            setState(() {
              _index = 2;
            });
          },
        ),
      ],
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99