flutter widget組件之-----------佈局組件(單個子元素)
widget分爲兩類:widgets library中的標準widget和Material Components library中的專用widget;任何應用程序都可以使用widgets library中的widget,但只有Material應用程序可以使用Material Components庫。其中Card,ListTitle就是Material Components庫中的組件。
Container
一個擁有繪製、定位、調整大小的 widget
- 構造函數
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,// 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Container(
// color: Colors.red, // 裝飾器的簡單寫,與裝飾器不能共存
// 條件約束,
constraints: new BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
// 裝飾器 給容器添加的樣式
decoration: new BoxDecoration(
border: new Border.all(width: 2.0, color: Colors.red),
color: Colors.grey,
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
image: new DecorationImage(
image: new NetworkImage(
'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
),
),
padding: const EdgeInsets.all(8.0),// 內邊距 都爲8
alignment: Alignment.center,// 居中對齊
// 子組件
child: new Text('Hello World',
style: Theme
.of(context)
.textTheme
.display1
.copyWith(color: Colors.black)),
// 繞着z軸旋轉 多少弧度
transform: new Matrix4.rotationZ(0.3),
),
],
),
),
);
}
}
Padding
一個widget, 會給其子widget添加指定的填充
- 構造函數
Padding({
Key key,
@required this.padding,// 內邊距
Widget child,// 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Padding(
// 內邊距
padding: const EdgeInsets.fromLTRB(20.0, 50.0, 40.0, 40.0),
// 子組件
child: new Text("Padding"),
)
],
),
),
);
}
}
Center Align
Align:一個widget,它可以將其子widget對齊,並可以根據子widget的大小自動調整大小。
Center:將其子widget居中顯示在自身內部的widget,繼承了Align
- 構造函數
Align({
Key key,
this.alignment = Alignment.center,// 對齊方式
this.widthFactor,//大於等於1.0的正數,用於計算此組件的寬度,子組件的寬度乘以此寬度因子
this.heightFactor,//大於等於1.0的正數,用於計算此組件的高度,子組件的寬度乘以此高度因子
Widget child // 子組件
})
Center({
Key key,
double widthFactor, //大於等於1.0的正數,用於計算此組件的寬度,子組件的寬度乘以此寬度因子
double heightFactor, //大於等於1.0的正數,用於計算此組件的高度,子組件的寬度乘以此高度因子
Widget child // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Center(
widthFactor: 1.2,// 寬度因子
heightFactor: 2,// 高度因子
// 子組件
child: new Text("Center"),
),
Align(
// 對齊方式,1.0表示最右邊的邊,0表示中心 ,-1表示最左邊的邊
alignment: const Alignment(1.0, 0),
widthFactor: 3.0, // 寬度因子
heightFactor: 3.0,// 高度因子
// 子組件
child: new Container(
child: new Text("Align"),
color: Colors.amber,
),
),
],
),
),
);
}
}
FittedBox
按自己的大小調整其子widget的大小和位置。
- 構造函數
FittedBox({
Key key,
this.fit = BoxFit.contain,// 子項如何填充佈局空間, contain cover等
this.alignment = Alignment.center,// 對齊方式
Widget child,//子項
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Container(
color: Colors.amberAccent,
alignment: Alignment.center,
width: double.infinity,
height: double.infinity,
// fittedbox
child: new FittedBox(
fit: BoxFit.fill,// 通過子項長寬比率來填充
alignment: Alignment.center,// 居中
// 子項
child: new Container(
color: Colors.red,
child: new Text(
"BoxFit.fill",
style: const TextStyle(fontSize: 20.0),
),
),
),
),
],
),
),
);
}
}
AspectRatio
一個widget,試圖將子widget的大小指定爲某個特定的長寬比。
- 構造函數
AspectRatio({
Key key,
@required this.aspectRatio, // 長寬比率,不能爲空
Widget child // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Container(
height: 200.0,
// aspectRatio佈局
child: new AspectRatio(
aspectRatio: 2,// 長款比率
//子組件
child: new Container(
color: Colors.red,
),
),
)
],
),
),
);
}
}
ConstrainedBox
對其子項施加附加約束的widget
- 構造函數
ConstrainedBox({
Key key,
@required this.constraints,// 子組件佈局的約束條件
Widget child // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new ConstrainedBox(
// 約束條件 限制的最小、最大長度和寬度
constraints: const BoxConstraints(
minWidth: 50.0,
minHeight: 50.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
// 子組件
child: new Container(
width: 20.0,
height: 20.0,
color: Colors.green,
),
)
],
),
),
);
}
}
Baseline
根據子項的基線對它們的位置進行定位的widget。
- 構造函數
Baseline({
Key key,
@required this.baseline,// 此組件頂部開始放置子組件的邏輯像素數
@required this.baselineType,// 基線類型 一個TextBaseline類型的實例 enum
Widget child // 子組件
})
TextBaseline {
///對齊字母字符底部的水平線
alphabetic,
///對齊表意字符的水平線
ideographic,
}
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Baseline(
baseline: 50.0,//// 此組件頂部開始放置子組件的邏輯像素數
///基線類型 對齊字母字符底部的水平線
baselineType: TextBaseline.alphabetic,
child: new Text(
'TjTjTj',
style: new TextStyle(
fontSize: 16.0,
textBaseline: TextBaseline.alphabetic,
),
),
),
new Baseline(
baseline: 50.0,
baselineType: TextBaseline.alphabetic,
child: new Container(
width: 30.0,
height: 30.0,
color: Colors.red,
),
),
new Baseline(
baseline: 50.0,
baselineType: TextBaseline.alphabetic,
child: new Text(
'RyRyRy',
style: new TextStyle(
fontSize: 35.0,
),
),
),
],
),
),
);
}
}
FractionallySizedBox
一個widget,它把它的子項放在可用空間的一小部分。關於佈局算法的更多細節,見RenderFractionallySizedOverflowBox。
- 構造函數
FractionallySizedBox({
Key key,
this.alignment = Alignment.center, // 對齊方式
this.widthFactor, // widthFactor >= 0.0用於計算此組件的寬度,子組件的寬度乘以此寬度因子
this.heightFactor,// heightFactor >= 0.0 用於計算此組件的高度,子組件的高度乘以此高度因子
Widget child, // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Container(
color: Colors.blue,
height: 150.0,
width: 150.0,
//padding: const EdgeInsets.all(10.0),
child: new FractionallySizedBox(
alignment: Alignment.topLeft,// 坐上頂點對齊
widthFactor: 0.5,// 0.5倍的寬
heightFactor: 0.5,// 0.5倍的高
// 子組件
child: new Container(
color: Colors.red,
),
),
)
],
),
),
);
}
}
IntrinsicHeight IntrinsicWidget
IntrinsicHeight: 一個widget,它將它的子widget的高度調整其本身實際的高度。
IntrinsicWidget: 一個widget,它將它的子widget的寬度調整其本身實際的寬度
- 構造函數
IntrinsicHeight({
Key key,
Widget child // 子組件
})
IntrinsicWidth({
Key key,
this.stepWidth, // 子組件的寬度:n*stepWidth
this.stepHeight, // 子組件的高度:n*stepHeight
Widget child // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new IntrinsicHeight(
// 子組件
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
// 子組件的高度,自動增加到與下面黃色container同高
children: <Widget>[
new Container(color: Colors.blue, width: 100.0),
new Container(color: Colors.red, width: 50.0,height: 50.0,),
new Container(color: Colors.yellow, width: 150.0,height: 100,),
],
),
),
Divider(height: 10,color: Colors.black,),
new IntrinsicWidth(
stepHeight: 50.0,
stepWidth: 40.0, // 子組件的寬度是此值得n倍,此處爲4倍,也就是160,因此。藍色、黃色container的寬度就會自適應到160
child: new Column(
children: <Widget>[
new Container(color: Colors.blue, height: 100.0),
new Container(color: Colors.red, width: 130.0, height: 100.0),
new Container(color: Colors.yellow, height: 150.0,),
],
),
)
],
),
),
);
}
}
LimitedBox
一個當其自身不受約束時才限制其大小的盒子。
- 構造函數
LimitedBox({
Key key,
this.maxWidth = double.infinity,// 沒有BoxConstraints.maxWidth約束的情況下的最大寬度約束
this.maxHeight = double.infinity,// 沒有BoxConstraints.maxHeight約束的情況下的最大高度約束
Widget child,// 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
Container(
color: Colors.red,
height: 100,
width: 250.0,
),
LimitedBox(
maxWidth: 100.0, // 沒有作用??
maxHeight: 50, // 最大高度
child: Container(
color: Colors.blue,
height: 100,
width: 250.0,
),
)
],
),
),
);
}
}
offstage
一個佈局widget,可以控制其子widget的顯示和隱藏。
- 構造函數
Offstage({
Key key,
this.offstage = true, // 控制子組件的顯示與隱藏,true爲隱藏,false爲顯示
Widget child // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
bool offstage;
@override
void initState() {
super.initState();
offstage = false;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
new Offstage(
offstage: offstage, // // 控制子組件的顯示與隱藏,true爲隱藏,false爲顯示
child: Container(color: Colors.blue, height: 100.0),
),
new CupertinoButton(
child: Text("點擊切換顯示"),
onPressed: () {
setState(() {
offstage = !offstage;
});
},
)
],
),
),
);
}
}
SizedBox OverflowBox SizedOverflowBox
SizedBox:一個特定大小的盒子。這個widget強制它的孩子有一個特定的寬度和高度。如果寬度或高度爲NULL,則此widget將調整自身大小以匹配該維度中的孩子的大小。
OverflowBox: 對其子項施加不同約束的widget,它可能允許子項溢出父級
SizedOverflowBox: 一個特定大小的widget,但是會將它的原始約束傳遞給它的孩子,它可能會溢出
- 構造函數
SizedBox({
Key key,
this.width, // 強制設置子組件的寬度,設置此值後,子組件的寬度將無效
this.height, // 強制設置子組件的高度,設置此值後,子組件的寬度將無效
Widget child // 子組件
})
OverflowBox({
Key key,
this.alignment = Alignment.center,// 對齊方式
this.minWidth,// 最小寬度
this.maxWidth,// 最大寬度
this.minHeight,// 最小高度
this.maxHeight,// 最大高度
Widget child,
})
SizedOverflowBox({
Key key,
@required this.size, // 組件大小設置
this.alignment = Alignment.center,// 對齊方式
Widget child, // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
Container(
color: Colors.green,
padding: const EdgeInsets.all(5.0),
child: SizedBox(
width: 100.0,// 設置此值後,子組件設置的寬度無效
height: 100.0,// 設置此值後,子組件設置的高度無效
child: Container(
color: Colors.red,
width: 50.0,
height: 150.0,
),
)
),
Divider(height: 15,color: Colors.black,),
Container(
color: Colors.green,
width: 100.0,
height: 100.0,
padding: const EdgeInsets.all(5.0),
// overflowBox包裹的子組件可以溢出容器container
child: OverflowBox(
alignment: Alignment.topLeft,// 坐上角對齊
maxWidth: 150.0, // 最大寬度
maxHeight: 150.0,// 最大高度
minWidth: 125.0, // 最小寬度
minHeight: 125.0,// 最小高度
// 設置最大最小高度和寬度之後,子組件設置的寬度,高度無效了,小於最小按最小,大於最大按最大
child: Container(
color: Colors.grey,
width: 100.0,
height: 100.0,
),
),
),
Divider(height: 50,color: Colors.black,),
Container(
color: Colors.green,
alignment: Alignment.topRight,
width: 100.0,
height: 100.0,
padding: EdgeInsets.all(5.0),
// 沒弄明白??
child: SizedOverflowBox(
size: Size(50.0, 100.0),// 設置width 50 高100
alignment: Alignment.topLeft,
child: Container(
color: Colors.red,
width: 100.0,
height: 50.0,
),
),
),
],
),
),
);
}
}
CustomSingleChildLayout
一個自定義的擁有單個子widget的佈局widget。
- 構造函數
CustomSingleChildLayout({
Key key,
@required this.delegate,// 控制自己佈局的委託
Widget child // 子組件
})
- 應用示例
class MyStatePageState extends State<MyStatePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("customPainter"),),
body: Center(
child: Column(
children: <Widget>[
Container(
color: Colors.blue,
padding: const EdgeInsets.all(5.0),
child: CustomSingleChildLayout(
// 子組件佈局委託類
delegate: FixedSizeLayoutDelegate(Size(200.0, 200.0)),
// 子組件
child: Container(
color: Colors.red,
width: 100.0,
height: 300.0,
),
),
)
],
),
),
);
}
}
// 控制子組件佈局的委託類
class FixedSizeLayoutDelegate extends SingleChildLayoutDelegate {
FixedSizeLayoutDelegate(this.size);
final Size size;
@override
Size getSize(BoxConstraints constraints) => size;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return new BoxConstraints.tight(size);
}
@override
bool shouldRelayout(FixedSizeLayoutDelegate oldDelegate) {
return size != oldDelegate.size;
}
}