- 涉及单个子元素布局类的Widget有:Container、Padding、Center、Align、FittedBox、AspectRatio、ConstrainedBox、Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth、LimitedBox、Offstage、OverflowBox、SizedBox、SizedOverflowBox、Transform、CustomSingleChildLayout,Positioned
Container(容器布局)
- Container是一个拥有绘制、定位、调整大小的widget,其构造方法如下:
Container({
Key key,
this.alignment,
this.padding,
this.color,
this.decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
this.clipBehavior = Clip.none,
})
image.png
-
child
:设置内部子组件;
-
margin
:设置外边距,container与临近组件之间的距离,属于EdgeInsets
类型;
-
padding
:设置内边距,container内部子控件距离container的内部边距,属于EdgeInsets
类型;
-
alignment
:内部子控件在container中的排列方式,属于Alignment
类型;
-
color
:container的背景颜色,属于Colors
类型;
-
decoration
:container的背景装饰,与color是互斥的不能同时存在
,decoration包含padding,不包含margin,可设置 边框、圆角、阴影、形状、渐变、背景图像,属于BoxDecoration
类型;
-
border
:设置边框,属于BoxBorder
类型;
-
gradient
:设置渐变色,属于Gradient
类型;
-
boxShadow
:设置阴影,属于List<BoxShadow>
类型;
-
width
,height
,constraints
:容器的大小可以通过width、height属性来指定,也可以通过constraints来指定,如果它们同时存在时,width、height优先。实际上Container内部会根据width、height来生成一个constraints;
-
transform
:设置container的变换矩阵,类型为Matrix4;
class SFHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
child: Text("520",style: TextStyle(color: Colors.white,fontSize: 38.0)), //设置子控件
alignment: Alignment.centerLeft, //设置内部布局
constraints: BoxConstraints.tightFor(width: 200.0,height: 200.0), //设置尺寸
margin: EdgeInsets.only(top: 120.0,left: 120.0), //设置外间距
padding: EdgeInsets.all(10.0), //设置内边距
decoration: BoxDecoration( //设置背景装饰
gradient: RadialGradient( //设置背景渐变色
colors: [Colors.red,Colors.orange],
center: Alignment.topLeft,
radius: .98
),
boxShadow: [ //设置背景阴影
BoxShadow(
color: Colors.black54,
offset: Offset(2.0,2.0),
blurRadius: 4.0
)
],
border: Border.all(//设置边框
width: 40.0,
color: Colors.purple
)
),
);
}
}
Snip20220214_13.png
Container的注意点
- Container在
没有设置宽高和child子组件时
,其尺寸大小 默认占据屏幕的剩余所有空间;
- Container在
只设置宽或者高时
,其没有设置的高或者宽默认占据屏幕的剩余所有空间;
- Container在
没有设置宽高时
,但设置了子组件child
,其尺寸大小与子组件等大;
- Container在
没有设置宽高时
,但设置了子组件child
,且设置了alignment属性
,其尺寸大小 默认占据屏幕的剩余所有空间;
Center(居中布局)
- 将子widget,
居中显示
在自身内部的widget,其构造函数如下:
Center({
Key key,
double widthFactor,
double heightFactor,
Widget child
})
-
widthFactor
:宽度因子;
-
heightFactor
:高度因子;
-
child
:内部子组件;
- 当widthFactor与heightFactor均为空时,Center的宽度尽可能最大,占据整个屏幕的宽度,Center的高度与内部child的高度相等;
- 当widthFactor = 2,heightFactor为空时,Center的宽度等于child的宽度 * 2,Center的高度与内部child的高度相等;
- 当heightFactor = 2,widthFactor为空时,Center的高度等于child的高度 * 2,Center的宽度尽可能最大,占据整个屏幕的宽度;
- 当widthFactor = 2,heightFactor = 2时,Center的宽度等于child的宽度 * 2,Center的高度等于child的高度 * 2;
- 案例代码如下:
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SFHomePage(),
);
}
}
class SFHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Flutter布局"),
),
body: SFHomeBody(),
);
}
}
class SFHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Column(
children: [
Container(
color: Colors.red,
child: Center(
child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
),
),
Container(
margin: EdgeInsets.only(top: 10.0),
color: Colors.red,
child: Center(
child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
widthFactor: 2,
),
),
Container(
margin: EdgeInsets.only(top: 10.0),
color: Colors.red,
child: Center(
child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
heightFactor: 2,
),
),
Container(
margin: EdgeInsets.only(top: 10.0),
color: Colors.red,
child: Center(
child: Text("Center",style: TextStyle(backgroundColor: Colors.green)),
widthFactor: 2,
heightFactor: 2,
),
)
],
);
}
}
image.png
Padding(填充布局)
- 一个widget,可以给其子节点添加填充(留白),实现内边距效果,其构造函数如下:
const Padding({
Key key,
@required this.padding,
Widget child,
})
-
padding
:设置内边距,属于EdgeInsets
类型,设置EdgeInsets的数值,通常有如下几种方式:
-
EdgeInsets.all(20)
:同时设置上下左右四个方向的内边距,且数值相同;
-
EdgeInsets.only(top: 10)
:可单独设置某个方向上的内边距;
-
EdgeInsets.fromLTRB(10, 10, 10, 10)
:同时设置四个方向上的内边距,数值不同;
-
EdgeInsets.symmetric(vertical: 15,horizontal: 25)
:设置垂直,水平方向上的内边距;
-
child
:设置子组件;
class SFHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Column(
children: [
Container(
color: Colors.red,
margin: EdgeInsets.only(top: 10),
child: Padding(
child: Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
),
),
Container(
color: Colors.red,
margin: EdgeInsets.only(top: 10),
child: Padding(
child: Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
padding: EdgeInsets.all(10)
)
),
Container(
color: Colors.purple,
margin: EdgeInsets.only(top: 10),
child: Padding(
child: Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
padding: EdgeInsets.only(left: 10,top: 15),
),
),
Container(
color: Colors.orange,
margin: EdgeInsets.only(top: 10),
child: Padding(
child: Text("Padding",style: TextStyle(color: Colors.white,fontSize: 28,backgroundColor: Colors.cyanAccent)),
padding: EdgeInsets.symmetric(vertical: 15,horizontal: 25),
),
)
],
);
}
}
image.png
- Padding可作为单个组件,也可作为属性,设置内边距;
Align(对齐布局)
- 一个widget,它可以将其子widget对齐,并可以根据子widget的大小自动调整大小,构造函数如下:
const Align({
Key key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget child,
})
-
alignment
:内部子组件的排列方式,属于Alignment
类型;
-
child
:内部子组件;
-
widthFactor
:宽度因子;
-
heightFactor
:高度因子;
- 当widthFactor与heightFactor均为空时,Align的宽度尽可能最大,占据整个屏幕的宽度,Align的高度与内部child的高度相等;
- 当widthFactor = 2,heightFactor为空时,Align的宽度等于child的宽度 * 2,Align的高度与内部child的高度相等;
- 当heightFactor = 2,widthFactor为空时,Align的高度等于child的高度 * 2,Align的宽度尽可能最大,占据整个屏幕的宽度;
- 当widthFactor = 2,heightFactor = 2时,Align的宽度等于child的宽度 * 2,Align的高度等于child的高度 * 2;
- widthFactor和heightFactor的原理与Center的完全一致;
class SFHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Column(
children: [
Container(
color: Colors.red,
margin: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
child: Container(
width: 50,
height: 50,
color: Colors.purple,
),
)
),
Container(
color: Colors.red,
margin: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
widthFactor: 2,
child: Container(
color: Colors.purple,
width: 50,
height: 50,
),
)
),
Container(
color: Colors.red,
margin: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
heightFactor: 2,
child: Container(
color: Colors.purple,
width: 50,
height: 50,
),
)
),
Container(
color: Colors.red,
margin: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
widthFactor: 2,
heightFactor: 2,
child: Container(
color: Colors.purple,
width: 50,
height: 50,
),
)
)
],
);
}
}
image.png
SizedBox
- SizedBox:可用来设置
两个widget之间的间距
,也可用来限制子组件的大小;
- 其构造函数如下:
const SizedBox({
Key key,
this.width,
this.height,
Widget child
})
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SFMinePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MaterialButton(
onPressed: (){},
onLongPress: (){},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Text(
"按钮"
),
color: Colors.blue,
),
SizedBox(
child: Container(
color: Colors.green,
),
height: 20,
width: 100,
),
TextField(
onChanged: (String text){},
decoration: InputDecoration(
filled: true,
fillColor: Colors.orange
),
)
]
),
);
}
}
image.png
OverflowBox
- OverflowBox:允许子组件,溢出父组件显示,其构造函数如下:
const OverflowBox({
Key key,
this.alignment = Alignment.center,
this.minWidth,
this.maxWidth,
this.minHeight,
this.maxHeight,
Widget child,
})
-
alignment
:在父组件中的对齐方式;
-
child
:设置子组件;
- minWidth:最小宽度,如果子控件宽度小于这个值,子控件按这个值显示;
- maxWidth:最大宽度,如果子控件宽度大于这个值,子控件按这个值显示;
- minHeight:最小高度,如果子控件高度小于这个值,子控件按这个值显示;
- maxHeight:最大高度,如果子控件高度大于这个值,子控件按这个值显示;
- 案例代码如下:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SFMinePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.orange,
width: 200,
height: 200,
padding: EdgeInsets.all(10),
child: OverflowBox(
alignment: Alignment.topLeft,
maxHeight: 300,
maxWidth: 300,
child: Container(
color: Colors.blue,
width: 350,
height: 350,
),
),
);
}
}
image.png
- 蓝色超出父组件 溢出显示;
- maxWidth最大宽度为300,虽然蓝色子组件设置了350,最终宽度按300显示;
SizeOverflowBox
- OverflowBox自身是没有尺寸的,但是SizedOverflowBox是有的,其构造函数如下:
const SizedOverflowBox({
Key key,
@required this.size,
this.alignment = Alignment.center,
Widget child,
})
-
size
:设置宽高;
-
child
:设置子组件;
-
alignment
:在父组件中的对齐方式;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SFMinePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Colors.blue,
child: SizedOverflowBox(
alignment: Alignment.topCenter,
size: Size(100, 50),
child: Container(
width: 50,
height: 80,
color: Colors.amber,
),
),
),
Container(
margin: EdgeInsets.only(top: 50),
color: Colors.blue,
height: 50,
constraints: BoxConstraints(
maxHeight: 50,
),
child: OverflowBox(
alignment: Alignment.topCenter,
minWidth: 20,
maxWidth: 100,
maxHeight: 100,
minHeight: 20,
child: Container(
width: 50,
height: 120,
color: Colors.amber,
),
),
)
],
);
}
}
image.png
Positioned
-
Positioned
:在Stack中,针对目标控件实现 定位,构造函数如下:
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
- left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离;
- width和height用于指定定位元素的宽度和高度;
class SFHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("SFHomePage build");
return Scaffold(
appBar: AppBar(
title: Text("商品列表"),
),
body: ui3()
);
}
Widget ui3() {
return Stack(
children: [
Container(
color: Colors.pink,
),
Positioned(
bottom: 30,
left: 10,
right: 10,
child: Container(
color: Colors.green,
height: 100,
),
)
],
);
}
}
image.png
网友评论