Flutter组件之Container
简介
A convenience widget that combines common painting, positioning, and sizing widgets.
一般我们会在将这个组件用于设置widget的背景样式,限制尺寸或者形状。Container可以帮助我们组合、装饰和定位子widget。
如果将widget包装在无参的container中,其外观不会发生任何变化
如果没有其他内容,container将根据其子容器自行调整大小
属性
Container({ Key key, this.alignment, this.padding, Color color, Decoration decoration, this.foregroundDecoration, double width, double height, BoxConstraints constraints, this.margin, this.transform, this.child, })
|
容器大小可以通过width和height来进行指定,也可以通过constraints来指定,同时存在以width和height优先,另外color和decoration也是互斥的
举个例子
class MyContainerDemo extends StatelessWidget { final String title;
MyContainerDemo({Key key, this.title}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Container( width: 300, height: 300, decoration: BoxDecoration( color: Colors.white, border: new Border.all( color: Colors.blue, width: 8, ), borderRadius: const BorderRadius.all(const Radius.circular(8)), ), child: Text( 'Container', textAlign: TextAlign.center, style: TextStyle(fontSize: 28), ), ), ), ); } }
|
Child
如果Container里面没有子控件,它就会填充整个屏幕;如果有子控件,Container就会自动适应子控件大小,Container只能容纳一个子控件
Alignment
Alignment属性主要有以下几个属性:Alignment、FractionalOffset、AlignmentDirectional。此属性是针对于Container内部的各个子控件的布局
举个例子,我在上面的demo中加入了alignment: Alignment.bottomCenter,可以看到Text控件的位置发生了变化
class MyContainerDemo extends StatelessWidget { final String title;
MyContainerDemo({Key key, this.title}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Container( width: 300, height: 300, decoration: BoxDecoration( color: Colors.white, border: new Border.all( color: Colors.blue, width: 8, ), borderRadius: const BorderRadius.all(const Radius.circular(8)), ), child: Text( 'Container', textAlign: TextAlign.center, style: TextStyle(fontSize: 28), ), alignment: Alignment.bottomCenter, ), ), ); } }
|
Alignment有很多的属性,为了方便理解他们的一个位置,我们可以画以下的一个图
- Alignment.bottomCenter 对应 Alignment(0.0, 1.0)
- Alignment.bottomLeft 对应 Alignment(-1.0, 1.0)
- Alignment.bottomRight 对应 Alignment(1.0, 1.0)
- Alignment.center 对应 Alignment(0.0, 0.0)
- Alignment.centerLeft 对应 Alignment(-1.0, 0.0)
- Alignment.centerRight 对应 Alignment(1.0, 0.0)
- Alignment.topCenter 对应 Alignment(0.0, -1.0)
- Alignment.topLeft 对应 Alignment(-1.0, -1.0)
- Alignment.topRight 对应 Alignment(1.0, -1.0)
除了直接使用类似于Alignment.topCenter这样的预制属性外,我们也可以使用Alignment将控件放在其他位置
FractionalOffset的坐标轴如下图
- FractionalOffset.bottomCenter 对应 FractionalOffset(0.5, 1.0)
- FractionalOffset.bottomLeft 对应 FractionalOffset(0.0, 1.0)
- FractionalOffset.bottomRight 对应 FractionalOffset(1.0, 1.0)
- FractionalOffset.center 对应 FractionalOffset(0.5, 0.5)
- FractionalOffset.centerLeft 对应 FractionalOffset(0.0, 0.5)
- FractionalOffset.centerRight 对应 FractionalOffset(1.0, 0.5)
- FractionalOffset.topCenter 对应 FractionalOffset(0.5, 0.0)
- FractionalOffset.topLeft 对应 FractionalOffset(0.0, 0.0)
- FractionalOffset.topRight 对应 FractionalOffset(1.0, 0.0)
AlignmentDirectional 的坐标轴如下图
- AlignmentDirectional.bottomCenter 对应 AlignmentDirectional(0.0, 1.0)
- AlignmentDirectional.bottomEnd 对应 AlignmentDirectional(1.0, 1.0)
- AlignmentDirectional.bottomStart 对应 AlignmentDirectional(-1.0, 1.0)
- AlignmentDirectional.center 对应 AlignmentDirectional(0.0, 0.0)
- AlignmentDirectional.centerEnd 对应 AlignmentDirectional(1.0, 0.0)
- AlignmentDirectional.centerStart 对应 AlignmentDirectional(-1.0, 0.0)
- AlignmentDirectional.topCenter 对应 AlignmentDirectional(0.0, -1.0)
- AlignmentDirectional.topEnd 对应 AlignmentDirectional(1.0, -1.0)
- AlignmentDirectional.topStart 对应 AlignmentDirectional(-1.0, -1.0)
Margin
Margin是指相邻的两个或者多个控件之间的距离,主要有以下几种方法
- EdgeInsets.all()
- EdgeInsets.symmetric()
- EdgeInsets.fromLTRB()
- EdgeInsets.only()
EdgeInsets.all()
主要用于添加四周约束,上下左右的Margin值一致
class MarginPropertyEdgeInsetsAllWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Container( color: Colors.white, alignment: AlignmentDirectional(0.0, 0.0), child: Container( color: Colors.green, margin: EdgeInsets.all(200), ), ), ); } }
|
实现效果如下:
EdgeInsets.symmetric()
主要用于添加垂直方向的约束
class MarginPropertyEdgeInsetsSymmetricWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Container( color: Colors.white, alignment: AlignmentDirectional(0.0, 0.0), child: Container( color: Colors.green, margin: EdgeInsets.symmetric(vertical: 50, horizontal: 50), ), ), ); } }
|
EdgeInsets.fromLTRB()
主要用于添加left、top、right、bottom四个方向的约束
class MarginPropertyEdgeInsetsFromLTRBWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Container( color: Colors.white, alignment: AlignmentDirectional(0.0, 0.0), child: Container( color: Colors.green, margin: EdgeInsets.fromLTRB(5, 50, 100, 100), ), ), ); } }
|
EdgeInsets.only()
用于约束哪些方向上的margin是非0的,不设置值默认为0
class MarginPropertyEdgeInsetsOnlyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Container( color: Colors.white, alignment: AlignmentDirectional(0.0, 0.0), child: Container( color: Colors.green, margin: EdgeInsets.only(), ), ), ); } }
|
在这个例子中 ,我们四个方向都没有设置值,那么它四个方向的默认值都是0
Padding
既然有了Margin,那么怎么能少了Padding,不同之处在于Padding主要是设置主控件内部子控件之间的间距,举个例子:
class MyContainerDemo extends StatelessWidget { final String title;
MyContainerDemo({Key key, this.title}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Container( width: 300, height: 300, decoration: BoxDecoration( color: Colors.white, border: new Border.all( color: Colors.blue, width: 8, ), borderRadius: const BorderRadius.all(const Radius.circular(8)), ), child: Text( 'Container', textAlign: TextAlign.center, style: TextStyle(fontSize: 28), ), padding: EdgeInsets.all(50), ), ), ); } }
|
效果就是这样的
Container中的Transform属性可以通过使用不同的Matrix从而实现多种多样的变化,举个例子:
class MyContainerDemo extends StatelessWidget { final String title;
MyContainerDemo({Key key, this.title}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Container( width: 300, height: 300, decoration: BoxDecoration( color: Colors.white, border: new Border.all( color: Colors.blue, width: 8, ), borderRadius: const BorderRadius.all(const Radius.circular(8)), ), child: Text( 'Container', textAlign: TextAlign.center, style: TextStyle(fontSize: 28), ), alignment: Alignment.bottomCenter, transform: Matrix4.rotationY(0.5), ), ), ); } }
|
变换前和变换后的效果对比如下: