【Flutter】十一、Flutter中常用的容器类
Flutter中的容器作用常常是用来包裹某个组件,所以都会有一个child属性,注意这里是child不是children,children属性是大部分布局类都有的属性。Flutter常用的容器类有:Center、Padding、AnimatedPadding、Container、SizedBox、FractionallySizedBox、SizedOverflowBox、OverflowBox、LimtedBox、ConstrainedBox、DecoratedBox、FittedBox、RotateBox、UnconstrainedBox、Transform、Align.
一、Center
Center容器用来居中widget
构造函数
const Center({
Key key,
double widthFactor, // 若该值为空,该组件宽度会尽可能大;若不为空,该组件的宽度就是子节点宽度的多少倍
double heightFactor, // 同widthFactor
Widget child // 子组件
}) : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
示例
import 'package:flutter/material.dart';
class CenterDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
widthFactor: 3.0,
heightFactor: 1.0,
child: Text(
'这是居中文本',
style: TextStyle(
color: Colors.red,
fontSize: 15
),
),
);
}
}
二、Padding
内边距Widget,与CSS中的padding相似。
下图是一个未使用Padding的Container,左右两侧都紧邻两边:
使用Padding后,距离上下左右均有20的距离:
import 'package:flutter/material.dart';
class PaddingDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Padding(
// 下面四种方法均可实现上下左右20内边距
padding: EdgeInsets.all(20.0),
// padding: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 20.0),
// padding: EdgeInsets.only(left: 20.0, top: 20.0, right: 20.0, bottom: 20.0),
// padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0),
child: Container(
height: 100,
width: 180,
color: Colors.red
),
);
}
}
构造函数
const Padding({
Key key,
@required this.padding, // 设置内边距
Widget child,
}) : assert(padding != null),
super(key: key, child: child);
Padding的padding属性
Padding的padding属性可通过以下方法进行定义:
方法 | 说明 |
---|---|
EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom) | 为上下左右分别设置内边距 |
EdgeInsets.all(double value) | 上下左右统一设置内边距 |
EdgeInsets.only({this.left = 0.0, this.top = 0.0, this.right = 0.0, this.bottom = 0.0 }) | 可单独为上下左右四个方向设置内边距 |
EdgeInsets.symmetric({double vertical = 0.0, double horizontal = 0.0}) | 可单独为水平和垂直方向设置内边距 |
三、AnimatedPadding
会产生动画效果的padding,在给定时间内缩放到指定padding。
构造函数
AnimatedPadding({
Key key,
@required this.padding, // 内边距
this.child,
Curve curve = Curves.linear, // 动画运动速率
@required Duration duration, // 动画持续时间
Duration reverseDuration,
})
示例
import 'package:flutter/material.dart';
class AnimatedPaddingDemo extends StatefulWidget{
@override
_AnimatedPaddingDemoState createState() => _AnimatedPaddingDemoState();
}
class _AnimatedPaddingDemoState extends State{
double paddingVal = 20.0;
_changePadding () {
setState(() {
paddingVal = paddingVal == 20.0 ? 100.0 : 20.0;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
AnimatedPadding(
padding: EdgeInsets.all(paddingVal),
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: Container(
color: Colors.blue,
height: 200.0,
),
),
RaisedButton(
child: Text('toggle padding'),
onPressed: _changePadding,
)
],
);
}
}
四、Container
类似于HTML中的div标签
构造函数
Container({
Key key,
this.alignment, // 对齐方式
this.padding, // 内边距
Color color, // 背景色,不能与decoration同时指定
Decoration decoration, // 盒装饰属性,可设置widget的背景、边框等
this.foregroundDecoration,
double width, // 宽度
double height, // 高度
BoxConstraints constraints, // 也可显示widget宽高
this.margin, // 外边距
this.transform, // 变形,包括平移、旋转、倾斜等
this.child,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
),
decoration = decoration ?? (color != null ? BoxDecoration(color: color) : null),
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints,
super(key: key);
示例
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:vector_math/vector_math_64.dart';
class ContainerDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
border: Border.all(
color: const Color(0xffff0000),
width: 2.0,
),
color: const Color(0xFFfff000),
image: DecorationImage(
image: NetworkImage('http://pic33.nipic.com/20131007/13639685_123501617185_2.jpg'),
fit: BoxFit.fill
),
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
width: 300.0,
height: 150.0,
//color: Colors.blue,
padding: EdgeInsets.all(10.0),
margin: EdgeInsets.all(20.0),
constraints: BoxConstraints.expand(width: 200.0, height: 150.0),
// foregroundDecoration: BoxDecoration(
// border: Border.all(
// color: const Color(0xFFd00a7f),
// width: 2.0
// )
// ),
transform: Matrix4.translation(Vector3(20.0, 30.0, 0)),
child: Text(
'Container demo',
style: TextStyle(
color: const Color(0xFFFF0000)
),
),
);
}
}
五、SizedBox
SizedBox有两种用法:一是可用来设置两个widget之间的间距,二是可以用来限制子组件的大小。
SizedBox相关方法使用
方法 | 说明 |
---|---|
SizedBox({ Key key, this.width, this.height, Widget child }) | 设置子组件宽高为任意值 |
SizedBox.expand({ Key key, Widget child }) | 使SizedBox充满整个父组件,height与width为infinity |
SizedBox.shrink({ Key key, Widget child }) | 使SizedBox尽可能小,height与width为0 |
SizedBox.fromSize({ Key key, Widget child, Size size }) | 同SizedBox() |
使用示例
Widget sizedBox1 = SizedBox(
width: double.infinity,
height: 100.0,
child: RaisedButton(
child: Text('pressed'),
onPressed: () => {},
)
);
Widget sizedBox2 = SizedBox.expand(
child: RaisedButton(
child: Text('pressed'),
onPressed: () => {},
)
);
Widget sizedBox3 = SizedBox.fromSize(
size: Size(100.0, 50.0),
child: RaisedButton(
child: Text('pressed'),
onPressed: () => {},
)
);
六、FractionallySizedBox
用法与SizedBox类似,只不过FractionallySizedBox的宽高是百分比大小,widthFactor,heightFactor参数就是相对于父控件的比例。注意设置FractionallySizedBox宽高后,其子组件设置的宽高将不起作用
const FractionallySizedBox({
Key key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget child,
}) : assert(alignment != null),
assert(widthFactor == null || widthFactor >= 0.0),
assert(heightFactor == null || heightFactor >= 0.0),
super(key: key, child: child);
示例
Widget fractionallySizedBox = FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5,
alignment: Alignment.topLeft,
child: SizedBox.fromSize(
size: Size(100.0, 70.0), // 不起作用
child: RaisedButton(
child: Text('pressed'),
onPressed: () => print('1'),
),
)
);
七、SizedOverflowBox
子组件在超出SizedOverflowBox指定的宽高时,不会隐藏,依然进行绘制
如下是一个大小为150*100的SizedOverflowBox,其包含了一个大小为200*200的Container子组件,你会发现Container超出SizedOverflowBox的部分依然会显示:
import 'package:flutter/material.dart';
class SizedOverflowBoxDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return SizedOverflowBox(
size: Size(150.0, 100.0),
child: Container(
height: 200.0,
width: 200.0,
color: Colors.blue,
)
);
}
}
构造函数
const SizedOverflowBox({
Key key,
@required this.size,
this.alignment = Alignment.center,
Widget child,
})
八、OverflowBox
限制子组件的宽高。
如下蓝色的Container的最大高度不会超过80,最小高度不会小于50:
import 'package:flutter/material.dart';
class OverflowBoxDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
height: 100.0,
width: 100.0,
color: Colors.red,
child: OverflowBox(
minHeight: 50.0,
maxHeight: 80.0,
child: Container(
width: 100.0,
height: 200.0,
color: Colors.blue,
),
),
);
}
}
九、LimtedBox
对最大宽高进行约束的控件(前提是LimitedBox不受约束)。如果LimitedBox外部宽度没有受到约束,child宽度会受到LimitedBox的maxWidth属性的限制,参考LimtedBoxRowDemo;高度同理,参考LimitedBoxColumnDemo。
import 'package:flutter/material.dart';
class LimtedBoxRowDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Row(
children: [
LimitedBox(
maxWidth: 150.0,
maxHeight: 200.0, // 不会生效
child: Container(
color: Colors.lightGreen,
width: 250.0,
height: 400.0,
),
),
],
);
}
}
class LimitedBoxColumnDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Column(
children: <Widget>[
LimitedBox(
maxHeight: 100.0,
maxWidth: 200.0, // maxWidth不会生效
child: Container(
color: Colors.blue,
height: 300.0,
width: 300.0,
),
)
],
);
}
}
十、ConstrainedBox
对子控件施加宽高的约束。
下面的Container的高度最小不会小于50,最大不会超出100
import 'package:flutter/material.dart';
class ConstrainedBoxDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 100.0,
minHeight: 50.0,
maxWidth: 100.0,
minWidth: 50.0
),
child: Container(
height: 1000.0,
width: 1000.0,
color: Colors.red,
)
);
}
}
十一、DecoratedBox
装饰容器,在其子widget绘制前(或后)绘制一个装饰Decoration(如背景、边框、渐变等)
下面示例使用DecoratedBox创建了的带有渐变、圆角及阴影的控件:
import 'package:flutter/material.dart';
class DecoratedBoxDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
margin: EdgeInsets.all(10.0),
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xffadf30e), Color(0xff3896fe)],
),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.black45,
offset: Offset(3.0, 3.0),
blurRadius: 6.0
)
]
),
child: Container(
height: 100.0,
),
),
);
}
}
十二、FittedBox
根据fit属性决定在父控件中如何调整大小。BoxFit.contain以同比例缩放至最大;BoxFit.fill填充满父控件宽高比改变;BoxFit.cover等比例填充满父控件;BoxFit.fitWidth以宽度填充满父控件,宽高比可能改变;BoxFit.fitHeight同BoxFit.fitWidth;BoxFit.scaleDown等比例缩放至合适大小。
BoxFit | 效果 |
---|---|
Boxfit.none | |
BoxFit.contain | |
BoxFit.fill | |
BoxFit.cover | |
BoxFit.fitWidth | |
BoxFit.fitHeight | |
BoxFit.scaleDown |
测试代码
Container(
height: 120.0,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: const Color(0xffff0000)
)
),
margin: EdgeInsets.symmetric(vertical: 10.0,horizontal: 40.0),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Image(
image: NetworkImage('http://pic39.nipic.com/20140307/13928177_195158772185_2.jpg'),
),
),
);
十三、RotateBox
将child顺时针旋转,quarterTurns为1时表示旋转90°,2表示180°,以此类推,quarterTurns只能为整数。
示例代码
RotatedBox(
quarterTurns: 2,
child: Text(
'RotatedBox demo.'
),
);
十四、UnconstrainedBox
不施加任何约束的控件,使child按照原始尺寸渲染,与ConstrainedBox作用相反。
十五、Transform
对child施加变形(旋转,倾斜,平移,缩放)。
方法 | 说明 |
---|---|
Transform() | 各种变形 |
Transform.rotate() | 旋转 |
Transform.translate() | 平移 |
Transform.scale() | 缩放 |
示例代码
import 'package:flutter/material.dart';
class TransformDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
child: Transform(
origin: Offset(25,25),
transform: Matrix4.skew(1.0, 1.0),
child: Container(
height: 50.0,
width: 50.0,
color: Colors.red,
),
),
);
}
}
十六、Align
指定child对齐方式并可决定其大小。
示例代码
Container(
height: 300.0,
color: Colors.redAccent,
child: Align(
alignment: Alignment.center,
widthFactor: 2.0,
heightFactor: 2.0,
child: Text(
'Align demo',
style: TextStyle(
color: Colors.white
),
),
),
);