多个元素水平垂直布局

  • Row 水平布局
  • Column 垂直布局
  • Row、Column、Flex会被Expanded撑开,充满主轴可用空间
  • Row、Column、Flex会被Flexible撑开,充满副轴可用空间

MainAxisAlignment(主轴)和CrossAxisAlignment(副轴)常用于Row和Column控件中,主要是用来控制子控件排列的位置,并可以配合textDirection和verticalDirection属性来控制子控件排列的方向及改变MainAxisAlignment和CrossAxisAlignment的起始位置。

image.png

  1. new Column(
  2. children: <Widget>[
  3. new Row( // 默认居左
  4. mainAxisAlignment: MainAxisAlignment.start,
  5. children: [
  6. Material(
  7. color: Colors.red,
  8. child: Text('1'),
  9. ),
  10. Material(
  11. color: Colors.blue,
  12. child: Text('2'),
  13. ),
  14. Material(
  15. color: Colors.green,
  16. child: Text('3'),
  17. ),
  18. ],
  19. ),
  20. new Row( // 居中
  21. mainAxisAlignment: MainAxisAlignment.center,
  22. children: [
  23. Material(
  24. color: Colors.red,
  25. child: Text('11'),
  26. ),
  27. Material(
  28. color: Colors.blue,
  29. child: Text('22'),
  30. ),
  31. Material(
  32. color: Colors.green,
  33. child: Text('33'),
  34. ),
  35. ],
  36. ),
  37. new Row( // 居右
  38. mainAxisAlignment: MainAxisAlignment.end,
  39. children: [
  40. Material(
  41. color: Colors.red,
  42. child: Text('111'),
  43. ),
  44. Material(
  45. color: Colors.blue,
  46. child: Text('222'),
  47. ),
  48. Material(
  49. color: Colors.green,
  50. child: Text('333'),
  51. ),
  52. ],
  53. ),
  54. new Row( // 将主轴空白位置进行均分,排列子元素,手尾没有空隙
  55. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  56. children: [
  57. Material(
  58. color: Colors.red,
  59. child: Text('1111'),
  60. ),
  61. Material(
  62. color: Colors.blue,
  63. child: Text('2222'),
  64. ),
  65. Material(
  66. color: Colors.green,
  67. child: Text('3333'),
  68. ),
  69. ],
  70. ),
  71. new Row( // 将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
  72. mainAxisAlignment: MainAxisAlignment.spaceAround,
  73. children: [
  74. Material(
  75. color: Colors.red,
  76. child: Text('111111'),
  77. ),
  78. Material(
  79. color: Colors.blue,
  80. child: Text('222222'),
  81. ),
  82. Material(
  83. color: Colors.green,
  84. child: Text('333333'),
  85. ),
  86. ],
  87. ),
  88. new Row( // 将主轴空白区域均分,使各个子控件间距相等
  89. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  90. children: [
  91. Material(
  92. color: Colors.red,
  93. child: Text('1111111'),
  94. ),
  95. Material(
  96. color: Colors.blue,
  97. child: Text('2222222'),
  98. ),
  99. Material(
  100. color: Colors.green,
  101. child: Text('3333333'),
  102. ),
  103. ],
  104. ),
  105. new Row(
  106. children: [
  107. new Expanded(
  108. child: Material(
  109. color: Colors.red,
  110. child: Text('11111111'),
  111. )
  112. ),
  113. new Expanded(
  114. child: Material(
  115. color: Colors.blue,
  116. child: Text('22222222'),
  117. )
  118. ),
  119. new Expanded(
  120. child: Material(
  121. color: Colors.green,
  122. child: Text('33333333'),
  123. )
  124. ),
  125. ],
  126. ),
  127. new Row(
  128. children: [
  129. new Expanded(
  130. child: Material(
  131. color: Colors.red,
  132. child: Text('111111111'),
  133. )
  134. ),
  135. new Expanded(
  136. child: Material(
  137. color: Colors.blue,
  138. child: Text('222222222'),
  139. ),
  140. flex: 2, // 中间宽度是两边的 2 倍
  141. ),
  142. new Expanded(
  143. child: Material(
  144. color: Colors.green,
  145. child: Text('333333333'),
  146. )
  147. ),
  148. ],
  149. ),
  150. ],
  151. ),
  152. )

通过 Padding 实现边距布局

  1. Padding(
  2. padding: EdgeInsets.all(4),
  3. child: Text('padding widget')
  4. )
  5. Padding(
  6. padding: EdgeInsets.only(left: 4, top: 4 right: 4, bottom: 4),
  7. child: Text('padding widget')
  8. )
  9. Container(
  10. width: MediaQuery.of(context).size.width,
  11. padding: EdgeInsets.only(left: 8, bottom: 6, right: 0, top: 6),
  12. child: Text(
  13. 'Container 实现padding布局',
  14. style: new TextStyle(
  15. color: Color.fromARGB(255, 255, 255, 255),
  16. fontSize: 20,
  17. ),
  18. ),
  19. )

通过 Container 或 Material 容器组件 color 实现背景色

  1. Container(
  2. width: MediaQuery.of(context).size.width,
  3. padding: EdgeInsets.only(left: 8, bottom: 6, right: 0, top: 6),
  4. color: Colors.black38,
  5. child: Text(
  6. '通过 Container 的 color 属性可以实现文字背景色',
  7. style: new TextStyle(
  8. color: Color.fromARGB(255, 255, 255, 255),
  9. fontSize: 20,
  10. ),
  11. ),
  12. )
  13. Material(
  14. borderRadius: BorderRadius.circular(8), // 圆角
  15. color: Colors.white
  16. )

通过 BoxDecoration 实现图片圆角

  1. new Container(
  2. height: 240,
  3. decoration: BoxDecoration(
  4. image: DecorationImage(
  5. image: NetworkImage('https://cdn.jsdelivr.net/gh/flutterchina/website@1.0/images/homepage/screenshot-1.png'),
  6. fit: BoxFit.cover,
  7. ),
  8. borderRadius: BorderRadius.only(
  9. topLeft: Radius.circular(8.0),
  10. topRight: Radius.circular(8.0)),
  11. ),
  12. ),

通过 FlatButton.icon 实现左边 Icon + 右边文字的布局模式

image.png

  1. FlatButton.icon(
  2. icon: Icon(
  3. Icons.share,
  4. color: Colors.white,
  5. ),
  6. label: Text(
  7. '分享',
  8. style: new TextStyle(
  9. color: Colors.white,
  10. ),
  11. ), //`Text` to display
  12. onPressed: () {
  13. // click implement
  14. },
  15. )

通过 Stack + Position 层级叠加和绝对定位布局

  • Stack 可以实现层级布局,children 后面的 widget 会覆盖到上面
  • Position 可以实现绝对定位

image.png

  1. Stack(
  2. children: <Widget>[
  3. Positioned(
  4. child: new Image(
  5. image: NetworkImage('https://cdn.jsdelivr.net/gh/flutterchina/website@1.0/images/homepage/screenshot-2.png'),
  6. width: double.infinity,
  7. height: 240,
  8. fit: BoxFit.cover,
  9. ),
  10. ),
  11. Positioned(
  12. bottom: 0,
  13. child: Container(
  14. width: MediaQuery.of(context).size.width,
  15. padding: EdgeInsets.only(left: 8, bottom: 6, right: 0, top: 6),
  16. color: Colors.black54,
  17. child: Text('回家路上,顺便拯救了下地球',
  18. style: TextStyle(
  19. color: Colors.white,
  20. fontSize: 20.0
  21. ),
  22. maxLines: 1,
  23. overflow: TextOverflow.ellipsis
  24. ),
  25. )
  26. ),
  27. ],
  28. )