- Flex 弹性(流式)布局
- Wrap 包裹,自动换行布局
- SingleChildScrollView 滚动布局
- FittedBox 负责对组件进行缩放和位置调整
- FractionallySizedBox 宽度和高度缩放(百分比布局)
- ConstrainedBox-限制约束或者LimitedBox(限制宽高)
- BaseLine 基线的对其方式
- Row 水平布局
- Column 垂直布局
AspectRatio调整宽高比示例
- Offstage 控制是否显示
OverflowBox溢出父容器显示示例
- Padding 填充布局
Table布局示例
- Transform矩阵转换示例
1.弹性布局(Flex)
- 允许子组件按照一定比例来分配父容器空间。
- 主要通过Flex和Expanded来配合实现
① Flex
- Flex组件可以沿着水平或垂直方向排列子组件
-
direction
:Axis.vertical
表示垂直方向Axis.horizontal
表示水平方向 -
flex
: 弹性系数,大于0会按比例来分割,等于0不会扩展占用的空间
效果图代码
通过 Expanded
和 Flex
实现
import 'package:flutter/material.dart';
class FlexWidget extends StatefulWidget {
FlexWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_FlexWidgetState createState() => _FlexWidgetState();
}
class _FlexWidgetState extends State<FlexWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flex"),
),
body: Column(
children: <Widget>[
Container(
height: 400.0,
child: Flex(
direction: Axis.vertical,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.yellow,
),
),
],
),
),
Container(
height: 120.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
// 子组件的排列方式为主轴两端对齐
children: <Widget>[
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
)),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
))
],
))
],
));
}
}
② Wrap
字面意思,包裹📦
- 把具有相同点的布局整合在一个大的布局组件之内
- 结局Row布局的局限:在水平位置上“撑破”了屏幕,这种情况可以使用
换行处理【Wrap】
- 常见属性
spacing : 水平方向间距
runSpacing : 垂直方向间距
效果图
效果图效果图代码
import 'package:flutter/material.dart';
class WrapWidget extends StatefulWidget {
WrapWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_WrapWidgetState createState() => _WrapWidgetState();
}
class _WrapWidgetState extends State<WrapWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Wrap"),
),
body: Column(
children: <Widget>[
Wrap(
spacing: 4.0,
runSpacing: 4.0,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
],
)
],
));
}
}
案例二
效果图
image.png代码
Wrap(
spacing: 8.0, // Chip之间的间距大小
runSpacing: 4.0, // 行之间的间距大小
children: <Widget>[
Chip(
//添加圆形头像
avatar: CircleAvatar(
backgroundColor: Colors.lightGreen.shade800, child: Text('西门', style: TextStyle(fontSize: 10.0),)),
label: Text('西门吹雪'),
),
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.lightBlue.shade700, child: Text('司空', style: TextStyle(fontSize: 10.0),)),
label: Text('司空摘星'),
),
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.orange.shade800, child: Text('婉清', style: TextStyle(fontSize: 10.0),)),
label: Text('木婉清'),
),
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.blue.shade900, child: Text('一郎', style: TextStyle(fontSize: 10.0),)),
label: Text('萧十一郎'),
),
],
)
③SingleChildScrollView-滚动布局
- 组件是负责滚动的,里面只能嵌套一个组件
- Column布局超出屏幕后不能滚动,需要在外层嵌套SingleChildScrollView才可以
- 可以设置滚动方向,也可以通过reverse 属性设置阅读顺序
- 还可以解决TextField布局溢出问题
④FittedBox 缩放
负责对组件进行缩放和位置调整
-
fit 缩放方式
缩放本身占据FittedBox的大小,默认值BoxFit.contain子组件的宽度或高度被缩放到父容器限定的值时,就会被停止缩放
- alignment 对齐方式
Row(
children: <Widget>[
Container(
color: Colors.blue,
width: 80.0,
height: 80.0,
margin: EdgeInsets.only(bottom: 10.0),
child: new FittedBox(
fit: BoxFit.contain,
alignment: Alignment.topLeft,
child: new Container(
color: Colors.yellow,
child: new Text("FittedBox"),
),
),
),
Text(
"BoxFit.contain",
style: new TextStyle(fontSize: 20.0),
)
],
)
15730043034089.jpg
⑤FractionallySizedBox 宽度和高度缩放(百分比布局)
- 基于宽度缩放因子和高度缩放因子来调整布局
- 大小有可能超出其父组件的设置
- 如果FractionallySizedBox中子组件设置了大小,则不会起作用,会被覆盖掉
Container(
color: Colors.blue,
height: 130.0,
width: 130.0,
padding: EdgeInsets.all(5.0),
child: new FractionallySizedBox(
alignment: Alignment.topLeft,
widthFactor: 1.5,//宽度因子
heightFactor: 0.5,//高度因子
child: new Container(
color: Colors.yellow,
),
),
)
15730905004805.jpg
⑥ConstrainedBox-限制约束或者LimitedBox(限制宽高)
- 在其约定范围内,其子组件是不能逾越的
- ConstrainedBox中主要是constraints起作用,而且这个值不能为null(空)
ConstrainedBox(
constraints: BoxConstraints(
minWidth: 100.0,
minHeight: 100.0,
maxWidth: 250.0,
maxHeight: 250.0,
),
child: new Container(
width: 500.0,
height: 300.0,
color: Colors.blue,
child: Text(
"100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000",
style: new TextStyle(color: Colors.black, fontSize: 20.0),
// 设置省略号
overflow: TextOverflow.ellipsis,
// 设置最大行数
maxLines: 1,
),
),
)
15730911486040.jpg
⑦BaseLine
- 一种基线的对其方式,把不相关的几个组件设置在同一条水平线上进行对齐
- baseline 设置位置,单位是浮点型(不能为空)
- baselineType 不能为空
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Baseline(
baseline: 80.0,
baselineType: TextBaseline.alphabetic,
child: new Text(
'今天天气真好',
style: new TextStyle(
fontSize: 18.0,
color: Colors.red,
textBaseline: TextBaseline.alphabetic,
),
),
),
new Baseline(
baseline: 100.0,
baselineType: TextBaseline.alphabetic,
child: new Text(
'适合晨练',
style: new TextStyle(
fontSize: 30.0,
color: Colors.blue,
textBaseline: TextBaseline.alphabetic,
),
),
),
new Baseline(
baseline: 120.0,
baselineType: TextBaseline.alphabetic,
child: FlutterLogo(
size: 100,
),
),
],
)
效果图
⑧Row 和 Column 水平和纵向布局
-
Column
不支持滚动,想支持滚动,需要考虑使用ListView
-
crossAxisAlignment
子组件在纵轴
的对其方式 -
mainAxisAlignment
子组件在水平方向
的对其方式 -
textDirection
布局顺序,从左至由,从右至左 -
mainAxisSize
max
表示尽可能多地占用水平方向位置,min
则反之
注意
- 在Row 和 Column 里CrossAxis 和 Main Axis 是不一样的
- Row 布局 设置
crossAxisAlignment
无效 - Column 布局 设置
mainAxisAlignment
无效
效果图
Flex 案例补充
static var c1 = Container(
width: 50,
height: 50,
color: Colors.blue,
);
static var c2 = Container(
width: 100,
height: 80,
color: Colors.red,
);
static var c3 = Container(
width: 150,
height: 50,
color: Colors.yellow,
);
var flex_test = Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: c1,
),
Expanded(
child: c2,
),
Expanded(
child: c3,
),
],
);
⑨AspectRatio调整宽高比示例
Container(
height: 200.0,
child: AspectRatio(
aspectRatio: 1.5,//比例可以调整
child: Container(
color: Colors.green,
),
),
)
Offstage 控制是否显示
//状态控制是否显示文本组件
bool offstage = true;
Center(
child: Offstage(
offstage: offstage,//控制是否显示
child: Text(
'我出来啦!',
style: TextStyle(
fontSize: 36.0,
),
),
),
)
OverflowBox溢出父容器显示示例
效果图
image.png代码
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('OverflowBox溢出父容器显示示例'),
),
body: Container(
color: Colors.green,
width: 200.0,
height: 200.0,
padding: const EdgeInsets.all(50.0),
child: OverflowBox(
alignment: Alignment.topLeft,
maxWidth: 400.0,
maxHeight: 400.0,
child: Container(
color: Colors.blueGrey,
width: 300.0,
height: 300.0,
),
),
));
}
}
Padding 填充布局
效果图
image.png代码
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Padding填充布局示例'),
),
body: Center(
//添加容器 外框
child: Container(
width: 300.0,
height: 300.0,
//容器内边距上下左右设置为60.0
padding: EdgeInsets.all(6.0),
//添加边框
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.green,
width: 8.0,
),
),
//添加容器 内框
child: Container(
width: 200.0,
height: 200.0,
//添加边框
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.blue,
width: 8.0,
),
),
//添加图标
child: FlutterLogo(),
),
),
),
);
}
}
Table布局示例
效果图
image.png代码
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Table布局示例'),
),
//表格居中
body: Center(
//添加表格
child: Table(
//设置表格有多少列,并且指定列宽
columnWidths: const <int, TableColumnWidth>{
//指定索引及固定列宽
0: FixedColumnWidth(100.0),
1: FixedColumnWidth(40.0),
2: FixedColumnWidth(80.0),
3: FixedColumnWidth(80.0),
},
//设置表格边框样式
border: TableBorder.all(color: Colors.black38, width: 2.0, style: BorderStyle.solid),
children: const <TableRow>[
//添加第一行数据
TableRow(
children: <Widget>[
Text('姓名'),
Text('性别'),
Text('年龄'),
Text('身高'),
],
),
//添加第二行数据
TableRow(
children: <Widget>[
Text('张三'),
Text('男'),
Text('26'),
Text('172'),
],
),
//添加第三行数据
TableRow(
children: <Widget>[
Text('李四'),
Text('男'),
Text('28'),
Text('178'),
],
),
],
),
),
);
}
Transform矩阵转换示例
效果图
image.png代码
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Transform矩阵转换示例'),
),
body: Center(
//父容器 作为背景
child: Container(
//背景颜色
color: Colors.grey,
//矩阵转换
child: Transform(
//对齐方式
alignment: Alignment.topRight,
//设置旋转值
transform: Matrix4.rotationZ(0.3),
//被旋转容器
child: Container(
padding: const EdgeInsets.all(8.0),
color: const Color(0xFFE8581C),
child: const Text('Transform矩阵转换'),
),
),
),
),
);
}
}
补充布局案例
效果图
C0F4CC9F9AEC39877CFB62652C1B5A52.jpg代码
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//风景区地址部分
Widget addressContainer = Container(
padding: const EdgeInsets.all(32.0),//此部分四周间隔一定距离
//水平布局
child: Row(
children: <Widget>[
Expanded(
//垂直布局
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, //次轴即水平方向左侧对齐
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 8.0),//与下面文本间隔一定距离
child: Text(
'风景区地址',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'湖北省十堰市丹江口市',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
//图标
Icon(
Icons.star,
color: Colors.red[500],
),
Text('66'),
],
),
);
//构建按钮组中单个按钮 参数为图标及文本
Column buildButtonColumn(IconData icon, String label) {
//垂直布局
return Column(
mainAxisSize: MainAxisSize.min,//垂直方向大小最小化
mainAxisAlignment: MainAxisAlignment.center,//垂直方向居中对齐
children: <Widget>[
Icon(icon, color: Colors.lightGreen[600]),//上面图标部分
Container(
//距离上面图标一定间距
margin: const EdgeInsets.only(top: 8.0),
//下面文本部分
child: Text(
label,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: Colors.lightGreen[600],
),
),
)
],
);
}
//按钮组部分
Widget buttonsContainer = Container(
//水平布局
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,//水平方向均匀排列每个元素
children: <Widget>[
buildButtonColumn(Icons.call, '电话'),
buildButtonColumn(Icons.near_me, '导航'),
buildButtonColumn(Icons.share, '分享'),
],
),
);
//风景区介绍文本部分
Widget textContainer = Container(
//设置上下左右内边距
padding: const EdgeInsets.all(32.0),
//文本块一定是用'''来引用起来
child: Text(
'''
武当山,中国道教圣地,又名太和山、谢罗山、参上山、仙室山,古有“太岳”、“玄岳”、“大岳”之称。位于湖北西北部十堰市丹江口市境内。东接闻名古城襄阳市,西靠车城十堰市 ,南望原始森林神农架,北临高峡平湖 丹江口水库。
明代,武当山被皇帝封为“大岳”、“治世玄岳”,被尊为“皇室家庙”。武当山以“四大名山皆拱揖,五方仙岳共朝宗”的“五岳之冠”地位闻名于世。
1994年12月,武当山古建筑群入选《世界遗产名录》,2006年被整体列为“全国重点文物保护单位” 。2007年,武当山和长城、丽江、周庄等景区一起入选 “欧洲人最喜爱的中国十大景区”。2010至2013年,武当山分别被评为国家5A级旅游区、国家森林公园、中国十大避暑名山、海峡两岸交流基地,入选最美 “国家地质公园”。
截至2013年,武当山有古建筑53处,建筑面积2.7万平方米,建筑遗址9处,占地面积20多万平方米,全山保存各类文物5035件。
武当山是道教名山和武当武术的发源地,被称为“亘古无双胜境,天下第一仙山”。武当武术,是中华武术的重要流派。元末明初,道士张三丰集其大成,开创武当派。
''',
softWrap: true,
),
);
return MaterialApp(
title: '布局综合示例',
//自定义主题,主体颜色为绿色风格
theme: ThemeData(
brightness: Brightness.light, //应用程序整体主题的亮度
primaryColor: Colors.lightGreen[600], //App主要部分的背景色
accentColor: Colors.orange[600], //前景色(文本、按钮等)
),
home: Scaffold(
appBar: AppBar(
//页面标题
title: Text(
'武当山风景区',
style: TextStyle(color: Colors.white),
),
),
//使用列表视图默认为垂直布局,并且子元素能够上下滚动
body: ListView(
children: <Widget>[
//风景图片
Image.asset(
'images/wudang.jpeg',
width: 600.0,
height: 240.0,
fit: BoxFit.cover, //图片填充整个父容器
),
addressContainer,
buttonsContainer,
textContainer,
],
),
),
);
}
}
网友评论