如需转载,请注明出处:Flutter学习笔记(23)--多个子元素的布局Widget(Rwo、Column、Stack、IndexedStack、Table、Wrap)
上一篇梳理了拥有单个子元素布局的Widget,今天来梳理一下拥有多个子元素布局的Widget。
-
Row
Row组件常见属性如下:
mainAxisAlignment:主轴的排列方式
crossAxisAlignment:次轴的排列方式
mainAxisSize:主轴应该占据多少空间,取值max为最大,min为最小
children:组件子元素,它的本质是一个List列表
对于Row来说,水平方向是主轴,垂直方向是次轴。
首先来看一下mainAxisAlignment属性值都有哪些
enum MainAxisAlignment { start,//将子控件放在主轴开始的位置 end,//将子控件放在主轴结束的位置 center,//将子控件放在主轴中间的位置 spaceBetween,//将主轴空白位置进行均分,排列子元素,首尾没有空隙 spaceAround,//将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半 spaceEvenly,//将主轴空白区域均分,使各个子空间间距相等 }
Demo示例:
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ new Text('11111111111'), new Text('22222222222'), new Text('33333333333') ], ), ), ); } }
-
Column
Column组件常见属性如下:
mainAxisAlignment:主轴的排列方式
crossAxisAlignment:次轴的排列方式
mainAxisSize:主轴应该占据多少空间,取值max为最大,min为最小
children:组件子元素,它的本质是一个List列表
对Column来说,垂直方向是主轴,水平方向是次轴,使用上和Row大同小异
Demo示例:
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ new Text('11111111111'), new Text('22222222222'), new Text('33333333333') ], ), ), ); } }
-
Stack
Stack/alignment:
Stack组件的每一个子组件要么定位,要么不定位,定位的子组件是用Positioned组件包裹的,Stack组件本身包含所有不定位的子组件,子组件根据alignment属性定位(默认为左上角)。然后根据定位的子组件的top、right、bottom、left属性将他们放置在Stack组件上。
Stack既然是允许子元素堆叠的组件,那么定位堆叠位置的属性值有哪些呢?
alignment属性值:bottomCenter 底部中间位置、bottomLeft 底部左侧位置、bottomRight 底部右侧位置、center 正中间位置、centerLeft 中间居左位置、centerRight 中间居右位置、topCenter 上部居中位置、topLeft 上部居左位置、topRight 上部居右位置
Demo示例:
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Center( child: new Stack( alignment: Alignment.centerLeft, children: <Widget>[ new Container( 200.0, height: 200.0, color: Colors.blue, ), new Text('这是一段文本') ], ), ), ), ); } }
Stack/Positioned:
上面的示例是通过系统提供的定位来给子元素进行堆叠,但是实际工作中,上面的几类属性值往往不能满足我们UI的需求,UI可能会要求子元素放在任何你想不到的位置,那么这时候就需要用到我们Positioned来进行定位了。
Positioned属性值:top 子元素相对顶部边界距离,left 子元素相对左侧边界距离,right 子元素相对右侧边界距离,bottom 子元素相对底部边界距离。
Demo示例:
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Center( child: new Stack( children: <Widget>[ new Container( 200.0, height: 200.0, color: Colors.blue, ), new Positioned( top: 20.0, left: 50.0, child: new Text('这是一段文本') ) ], ), ), ), ); } }
-
IndexedStack
IndexedStack继承自Stack,它的作用是显示第index个child,其他的child都是不可见的,所以IndexedStack的尺寸永远是和最大的子节点尺寸一致。由于IndexedStack是继承自Stack,所以它只比Stack多了一个index属性,即对应child的索引。
Demo示例:
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Center( child: new IndexedStack( index: 1, children: <Widget>[ new Container( 200.0, height: 200.0, color: Colors.blue, ), new Positioned( top: 20.0, left: 50.0, child: new Text('这是一段文本') ) ], ), ), ), ); } }
-
Table
Table表格布局,每一行的高度由其内容决定,每一列的宽度由columnWidths属性单独控制。
Table组件常见属性如下:
columnWidths:设置每一列的宽度。
defaultColumnWidth:默认的每一列宽度,默认情况下均分。
textDirection:文字方向。
border:表格边框。
defaultVerticalAlignment:默认垂直方向的对齐方式,top 放置在顶部、middle 垂直居中、bottom 放置在底部、baseline 文本baseline对齐、fill 充满整个cell
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Table( defaultVerticalAlignment: TableCellVerticalAlignment.bottom, // 设置表格有多少列,并且指定列宽 columnWidths:const <int,TableColumnWidth> { 0:FixedColumnWidth(40.0), 1:FixedColumnWidth(40.0), 2:FixedColumnWidth(60.0), 3:FixedColumnWidth(60.0), 4:FixedColumnWidth(130.0), }, // 设置表格边框样式 border: TableBorder.all( color: Colors.blue, 2.0, style: BorderStyle.solid ), children: const <TableRow>[ // 添加第一行数据 TableRow( children: <Widget>[ SizedBox( child: Text('姓名'), height: 30, ), Text('性别'), Text('年龄'), Text('身高'), Text('备注'), ], ), // 添加第二行数据 TableRow( children: <Widget>[ Text('张三'), Text('男'), Text('20'), Text('186'), Text('学渣'), ], ), // 添加第三行数据 TableRow( children: <Widget>[ Text('李四'), Text('男'), Text('20'), Text('188'), Text('学酥'), ], ), // 添加第四行数据 TableRow( children: <Widget>[ Text('王五'), Text('男'), Text('21'), Text('177'), Text('学霸'), ], ), // 添加第五行数据 TableRow( children: <Widget>[ Text('小梅'), Text('女'), Text('22'), Text('170'), Text('学神,需要重点培养'), ], ), ], ), ), ); } }
-
Wrap
import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Children Demo', home: new Scaffold( appBar: AppBar( title: new Text('Children Demo'), ), body: new Wrap( spacing: 3.0, runSpacing: 20.0,//纵轴方向的间距 alignment: WrapAlignment.end,//纵轴方向的对其方式 children: <Widget>[ new Chip( avatar: CircleAvatar( backgroundColor: Colors.blue, child: new Text('A'), ), label: new Text('文本一'), ), new Chip( avatar: CircleAvatar( backgroundColor: Colors.blue, child: new Text('B'), ), label: new Text('文本二'), ), new Chip( avatar: CircleAvatar( backgroundColor: Colors.blue, child: new Text('C'), ), label: new Text('文本三'), ), new Chip( avatar: CircleAvatar( backgroundColor: Colors.blue, child: new Text('D'), ), label: new Text('文本四'), ), new Chip( avatar: CircleAvatar( backgroundColor: Colors.blue, child: new Text('E'), ), label: new Text('文本五'), ), ], ), ), ); } }