目录
Flutter中拥有30多种预定义的布局widget,常用的有Container、Padding、Center、Flex、Row、Colum、ListView、GridView。
基本分类
- 基础布局组件:Container(容器布局),Center(居中布局),Padding(填充布局),Align(对齐布局),Colum(垂直布局),Row(水平布局),Expanded(配合Colum,Row使用),FittedBox(缩放布局),Stack(堆叠布局),overflowBox(溢出父视图容器)。
- 宽高尺寸处理:SizedBox(设置具体尺寸),ConstrainedBox(限定最大最小宽高布局),LimitedBox(限定最大宽高布局),AspectRatio(调整宽高比),FractionallySizedBox(百分比布局)
- 列表和表格处理:ListView(列表),GridView(网格),Table(表格)
- 其它布局处理:Transform(矩阵转换),Baseline(基准线布局),Offstage(控制是否显示组件),Wrap(按宽高自动换行布局)
Padding(填充布局)
一个widget, 会给其子widget添加指定的填充
Padding的布局分为两种情况:
- 当child为空的时候,view会无限大
- 当child不为空的时候,Padding会将布局约束传递给child,根据设置的padding属性,缩小child的布局尺寸。然后Padding将自己调整到child设置了padding属性的尺寸,在child周围创建空白区域。
import 'package:flutter/material.dart';
void main() => runApp(
new MaterialApp(home: new MyApp()),
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页'),
),
body: new Center(//Container位于body中心位置
child: new Container(
//设置后RaisedButton大小不变,Container围绕这RaisedButton向外扩大8像素
padding: EdgeInsets.all(8),
color: Colors.blue,
child: new RaisedButton(
//padding: EdgeInsets.all(20),
color: Colors.white,
onPressed: () {},
child: Text(
'按钮',
style:
TextStyle(color: Colors.black, backgroundColor: Colors.white),
),
),
),
),
);
}
}
Align(对齐布局)
一个widget,它可以将其子widget对齐,并可以根据子widget的大小自动调整大小。
属性
const Align({
Key key,
this.alignment: Alignment.center,//对齐方式,默认居中对齐
this.widthFactor,//宽度因子,如果设置的话,Align的宽度就是child的宽度乘以这个值,不能为负数。
this.heightFactor,//高度因子,如果设置的话,Align的高度就是child的高度乘以这个值,不能为负数。
Widget child
})
例子
void main() => runApp(
new MaterialApp(home: new MyApp()),
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页'),
),
body: new Align(
alignment: Alignment.center,
widthFactor: 2,
child: new Container(
//padding: EdgeInsets.all(8),
color: Colors.blue,
child: new RaisedButton(
//padding: EdgeInsets.all(20),
color: Colors.white,
onPressed: () {},
child: Text(
'按钮',
style:
TextStyle(color: Colors.black, backgroundColor: Colors.white),
),
),
),
),
);
}
}
Center(居中布局)
将其子widget居中显示在自身内部的widget
继承自Align,默认居中并且宽度和高度因子同Align一样。没什么好说的!
FittedBox(缩放布局)
按自己的大小调整其子widget的大小和位置。
- 如果外部有约束的话,按照外部约束调整自身尺寸,然后缩放调整child,按照指定的条件进行布局;
- 如果没有外部约束条件,则跟child尺寸一致,指定的缩放以及位置属性将不起作用。
const FittedBox({
Key key,
this.fit = BoxFit.contain,//缩放方式,枚举值。详细缩放效果看源码里面有链接
this.alignment = Alignment.center,//对齐方式。
Widget child,
})
void main() => runApp(
new MaterialApp(home: new MyApp()),
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页'),
),
body: new Center(
child: new Container(
color: Colors.amberAccent,
width: 200.0,
height: 100.0,
child: new FittedBox(
fit: BoxFit.fill, //填方式,详细请
alignment: Alignment.center,
child: new Container(
color: Colors.red,
child: new Text("FittedBox", style: TextStyle(fontSize: 22)),
),
),
),
),
);
}
}
缩放方式
AspectRatio(宽高比)
AspectRatio的作用是调整child到设置的宽高比
- AspectRatio首先会在布局限制条件允许的范围内尽可能的扩展,widget的高度是由宽度和比率决定的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。
- 如果在满足所有限制条件过后无法找到一个可行的尺寸,AspectRatio最终将会去优先适应布局限制条件,而忽略所设置的比率。
属性
aspectRatio:aspectRatio是宽高比,最终可能不会根据这个值去布局,具体则要看综合因素,外层是否允许按照这种比率进行布局,只是一个参考值。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页'),
),
body: new Center(
child: new Container(
color: Colors.blue,
width: 100.0,//仅设置宽100 aspectRatio 1.5 高度为50
//height: 100.0,宽高同时设置时,aspectRatio失效
child: new AspectRatio(
aspectRatio: 1.5,
child: new RaisedButton(
color: Colors.red,
child: new Text("FittedBox", style: TextStyle(fontSize: 22)),
onPressed: () {},
),
),
),
),
);
}
}
ConstrainedBox(限定最大最小宽高布局)
设置child widget最大的宽,高度限制和最小的宽高限制范围
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity,
});
minWidth 满足约束条件的最小宽度
maxWidth 满足约束条件的最大宽度;可能是[double.infinity](1.0 / 0.0)
minHeight 满足约束条件的最小高度
maxHeight 满足约束条件的最大高度;可能是[double.infinity](1.0 / 0.0)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页'),
),
body: new Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 100.0,
maxHeight: 100.0,
),
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.red,
),
),
),
);
}
}
上面约束最大的宽高为100,child Container设置的宽高为200.最后实际显示的是宽高为100。
UnconstrainedBox
这个控件不做详细介绍了,它跟ConstrainedBox相反,是不添加任何约束条件到child上,让child按照其原始的尺寸渲染。