Column —— 行佈局
一、使用方法
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,//設定主軸方向上的對齊方式
MainAxisSize mainAxisSize = MainAxisSize.max,//設定主軸方向佔有空間的值,預設是max (MainAxisSize的取值有兩種:max:根據傳入的佈局約束條件,最大化主軸方向的可用空間;min:與max相反,是最小化主軸方向的可用空間;)
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//設定交叉軸方向上的對齊方式
TextDirection textDirection,//設定文字的排列方向,可以通過在設定Row主軸的基礎上設定 改變主軸的方向
VerticalDirection verticalDirection = VerticalDirection.down,//設定主軸的基礎上,可以通過設定verticalDirection改變主軸的方向
TextBaseline textBaseline,//設定
List<Widget> children = const <Widget>[],//子控制元件列表
})
複製程式碼
1. 用於在垂直方向中顯示其子項,另通過
//todo 例子1. Column,用於在垂直方向中顯示其子項。
Column(
children: <Widget>[
//Expanded 用於展開Row,Column或Flex的子項的視窗小部件。
//使用“ Expanded”小部件可以擴充套件行,列或Flex的子項 以填充主軸中的可用空間(例如,水平為行或垂直為列)。如果擴充套件了多個子節點,則根據彈性因子將可用空間劃分為多個子節點。
Expanded(
//建構函式 擴充套件({ Key key, int flex:1, @required Widget child })
//@required child 為必填引數,指要填充的子控制元件
child: Text('Deliver features faster', textAlign: TextAlign.center),
// child: Text('Deliver ', textAlign: TextAlign.center),
//孩子最多可以與可用空間一樣大(但允許更小)
flex: 1,
//鍵
key: ValueKey("1"),
),
Expanded(
child: Text('Craft beautiful', textAlign: TextAlign.center),
//通過還在控制元件去強制填充可以用空間,會向兩邊擠壓,以適應這個子控制元件
flex: 1,
),
Expanded(
flex: 2,
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
)
複製程式碼
2. 為什麼我的列有黃色和黑色警告條紋?
如果列非靈活內容(那些未包含在 Expanded或Flexible小部件中的內容)在一起比列本身寬,則說該列已溢位。當列溢位時,該列沒有任何剩餘空間可在其Expanded和Flexible 子級之間共享。該列通過在溢位的邊緣上繪製黃色和黑色條紋警告框來報告此情況。如果列外側有空間,則溢位量以紅色字型列印。
//例子2 為什麼我的列有黃色和黑色警告條紋
Column(
children: <Widget>[
const FlutterLogo(
size: 200,
),
const Icon(
Icons.account_circle,
size: 300,
color: Colors.blue,
),
const Icon(
Icons.ac_unit,
size: 200,
color: Colors.yellow,
)
],
)
複製程式碼
3. 通過Expanded 包裹自適應均分分佈
可以解決例子2中的問題,將第二個子項包裝在Expanded小部件中,該小部件告訴列應該為該子項提供剩餘空間:
//例子3 通過Expanded 包裹自適應均分分佈
//解決方法 解決方法是將第二個子項包裝在Expanded小部件中,該小部件告訴該列應該為該子項提供剩餘空間:
Column(
children: <Widget>[
const Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: const FlutterLogo(),
)
),
const Expanded(
flex: 1,
child: Icon(
Icons.account_circle,
size: 300,
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Icon(
Icons.access_time,
size: 300,
color: Colors.yellow,
),
),
],
)
複製程式碼
二、常用屬性
1. 設定主軸方向上的對齊方式 —— mainAxisAlignment
-
在水平方向控制元件(Row):
-
MainAxisAlignment是水平的,預設起始位置在左邊,排列方向為從左至右,此時可以通過textDirection來改變MainAxisAlignment的起始位置和排列方向
-
在垂直方向的控制元件中(Column) :
-
MainAxisAlignment是垂直的,預設起始位置在上邊,排列方向為從上至下,此時可以通過verticalDirection來改變MainAxisAlignment的起始位置及排列方向
-
MainAxisAlignment 的列舉型別
enum MainAxisAlignment {
//將子控制元件放在主軸的開始位置
start,
//將子控制元件放在主軸的結束位置
end,
//將子控制元件放在主軸的中間位置
center,
//將主軸空白位置進行均分,排列子元素,手尾沒有空隙
spaceBetween,
//將主軸空白區域均分,使中間各個子控制元件間距相等,首尾子控制元件間距為中間子控制元件間距的一半
spaceAround,
//將主軸空白區域均分,使各個子控制元件間距相等
spaceEvenly,
}
複製程式碼
- 例子
// 例子5
Column(
mainAxisAlignment: MainAxisAlignment.start,
//todo 在設定Column主軸的基礎上,可以通過設定verticalDirection改變主軸的方向,
// verticalDirection的預設值為VerticalDirection.down,也就是從上至下的方向
// verticalDirection的預設值為VerticalDirection.up,也就是從下至上的方向
verticalDirection:VerticalDirection.down,
children: <Widget>[
Box("aaaaaaa"),
Box("bbbbbbb"),
Box("ccccccc")
],
)
複製程式碼
2. 設定交叉軸方向上的對齊方式 —— crossAxisAlignment
-
在水平方向控制元件(Row):
-
CrossAxisAlignment是垂直的,預設起始位置在中間,排列方向為從上至下,此時可以通過verticalDirection來改變CrossAxisAlignment的起始位置及排列方向
-
在垂直方向的控制元件中(Column) :
-
CrossAxisAlignment是水平的,預設起始位置在中間,此時可以通過textDirection來改變CrossAxisAlignment的起始位置
-
列舉型別
enum CrossAxisAlignment {
//將子控制元件放在交叉軸的起始位置
start,
//將子控制元件放在交叉軸的結束位置
end,
//將子控制元件放在交叉軸的中間位置
center,
//使子控制元件填滿交叉軸
stretch,
//將子控制元件放在交叉軸的上,並且與基線相匹配(不常用)
baseline,
}
複製程式碼
- 例子
//例子 7 在column的基礎上設定交叉軸
Column(
mainAxisAlignment: MainAxisAlignment.start,
//todo 預設為start 將子控制元件放在交叉軸的起始位置
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Box("aaaaaaa"),
Box("bbbbbbb"),
Box("ccccccc"),
Expanded(
flex: 2,
child: Text('Column crossAxisAlignment .'),
)
],
)
複製程式碼
3. 在設定Column主軸的基礎上,可以通過設定verticalDirection改變主軸的方向
// verticalDirection的預設值為VerticalDirection.down,也就是從上至下的方向
// verticalDirection的預設值為VerticalDirection.up,也就是從下至上的方向
複製程式碼
// 例子5
Column(
mainAxisAlignment: MainAxisAlignment.start,
//todo 在設定Column主軸的基礎上,可以通過設定verticalDirection改變主軸的方向,
// verticalDirection的預設值為VerticalDirection.down,也就是從上至下的方向
// verticalDirection的預設值為VerticalDirection.up,也就是從下至上的方向
verticalDirection:VerticalDirection.down,
children: <Widget>[
Box("aaaaaaa"),
Box("bbbbbbb"),
Box("ccccccc")
],
)
複製程式碼
三、一個完整的例子
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ColumnPageDemo(title: 'FlexPageDemo'),
);
}
}
class ColumnPageDemo extends StatefulWidget {
ColumnPageDemo({Key key, this.title}) : super(key: key);
final String title;
@override
_ColumnPageDemoState createState() => _ColumnPageDemoState();
}
class _ColumnPageDemoState extends State<ColumnPageDemo> {
void _incrementCounter() {
setState(() {
});
}
//描述此視窗小部件表示的使用者介面部分
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
//todo 這裡有個要注意的點就是如果父控制元件沒有設定大小,container預設是用子控制元件的大小去填充父控制元件的大小
height:MediaQuery.of(context).size.height, //獲取螢幕的高度
width: MediaQuery.of(context).size.width,//獲取螢幕的寬度,
child:
//todo 例子1. Column,用於在垂直方向中顯示其子項。
// Column(
// children: <Widget>[
// //Expanded 用於展開Row,Column或Flex的子項的視窗小部件。
// //使用“ Expanded”小部件可以擴充套件列,列或Flex的子項 以填充主軸中的可用空間(例如,水平為列或垂直為列)。如果擴充套件了多個子節點,則根據彈性因子將可用空間劃分為多個子節點。
// Expanded(
// //建構函式 擴充套件({ Key key, int flex:1, @required Widget child })
// //@required child 為必填引數,指要填充的子控制元件
// child: Text('Deliver features faster', textAlign: TextAlign.center),
//// child: Text('Deliver ', textAlign: TextAlign.center),
// //孩子最多可以與可用空間一樣大(但允許更小)
// flex: 1,
// //鍵
// key: ValueKey("1"),
// ),
// Expanded(
// child: Text('Craft beautiful', textAlign: TextAlign.center),
// //通過還在控制元件去強制填充可以用空間,會向兩邊擠壓,以適應這個子控制元件
// flex: 1,
// ),
// Expanded(
// flex: 2,
// child: FittedBox(
// fit: BoxFit.contain, // otherwise the logo will be tiny
// child: const FlutterLogo(),
// ),
// ),
// ],
// )
//todo 例子2 為什麼我的列有黃色和黑色警告條紋?
//如果列非靈活內容(那些未包含在 Expanded或Flexible小部件中的內容)在一起比列本身寬,則說該列已溢位。當列溢位時,該列沒有任何剩餘空間可在其Expanded和Flexible 子級之間共享。該列通過在溢位的邊緣上繪製黃色和黑色條紋警告框來報告此情況。如果列外側有空間,則溢位量以紅色字型列印。
// Column(
// children: <Widget>[
// const FlutterLogo(
// size: 200,
// ),
// const Icon(
// Icons.account_circle,
// size: 300,
// color: Colors.blue,
// ),
// const Icon(
// Icons.ac_unit,
// size: 200,
// color: Colors.yellow,
// )
// ],
// )
//todo 例子3 通過Expanded 包裹自適應均分分佈
//解決方法 解決方法是將第二個子項包裝在Expanded小部件中,該小部件告訴該列應該為該子項提供剩餘空間:
Column(
children: <Widget>[
const Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: const FlutterLogo(),
)
),
const Expanded(
flex: 1,
child: Icon(
Icons.account_circle,
size: 300,
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Icon(
Icons.access_time,
size: 300,
color: Colors.yellow,
),
),
],
)
//todo 例子4 MainAxisAlignment和CrossAxisAlignment詳解
//MainAxisAlignment(主軸)就是與當前控制元件方向一致的軸,而CrossAxisAlignment(交叉軸)就是與當前控制元件方向垂直的軸
//在水平方向控制元件中,Row
//MainAxisAlignment是水平的,預設起始位置在左邊,排列方向為從左至右,此時可以通過textDirection來改變MainAxisAlignment的起始位置和排列方向
//CrossAxisAlignment是垂直的,預設起始位置在中間,排列方向為從上至下,此時可以通過verticalDirection來改變CrossAxisAlignment的起始位置及排列方向
//在垂直方向的控制元件中,Column
//MainAxisAlignment是垂直的,預設起始位置在上邊,排列方向為從上至下,此時可以通過verticalDirection來改變MainAxisAlignment的起始位置及排列方向
//CrossAxisAlignment是水平的,預設起始位置在中間,此時可以通過textDirection來改變CrossAxisAlignment的起始位置
// enum MainAxisAlignment {
//
// //將子控制元件放在主軸的開始位置
// start,
//
// //將子控制元件放在主軸的結束位置
// end,
//
// //將子控制元件放在主軸的中間位置
// center,
//
// //將主軸空白位置進列均分,排列子元素,手尾沒有空隙
// spaceBetween,
//
// //將主軸空白區域均分,使中間各個子控制元件間距相等,首尾子控制元件間距為中間子控制元件間距的一半
// spaceAround,
//
// //將主軸空白區域均分,使各個子控制元件間距相等
// spaceEvenly,
// }
// 在設定主軸的基礎上設定 主軸的方向
// textDirection:TextDirection.rtl:從右到左
// textDirection:TextDirection.ltr:從左到右
// 例子4.1
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 在設定Row主軸的基礎上設定 改變主軸的方向
//// textDirection:TextDirection.rtl,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ],
// )
//// 例子4.2
// Column(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 在設定Column主軸的基礎上,可以通過設定verticalDirection改變主軸的方向,
// // verticalDirection的預設值為VerticalDirection.down,也就是從上至下的方向
// // verticalDirection的預設值為VerticalDirection.up,也就是從下至上的方向
// verticalDirection:VerticalDirection.down,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ]
// )
// 例子5
// Column(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 在設定Column主軸的基礎上,可以通過設定verticalDirection改變主軸的方向,
// // verticalDirection的預設值為VerticalDirection.down,也就是從上至下的方向
// // verticalDirection的預設值為VerticalDirection.up,也就是從下至上的方向
// verticalDirection:VerticalDirection.down,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ],
//
// )
//todo enum CrossAxisAlignment {
// //將子控制元件放在交叉軸的起始位置
// start,
//
// //將子控制元件放在交叉軸的結束位置
// end,
//
// //將子控制元件放在交叉軸的中間位置
// center,
//
////使子控制元件填滿交叉軸
// stretch,
//
////將子控制元件放在交叉軸的上,並且與基線相匹配(不常用)
// baseline,
// }
//例子 6 在row的基礎上設定交叉軸
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// //todo 預設為start 將子控制元件放在交叉軸的起始位置
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc")
// ],
// )
//例子 7 在column的基礎上設定交叉軸
// Column(
// mainAxisAlignment: MainAxisAlignment.start,
//// //todo 預設為start 將子控制元件放在交叉軸的起始位置
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Box("aaaaaaa"),
// Box("bbbbbbb"),
// Box("ccccccc"),
// Expanded(
// flex: 2,
// child: Text('Column crossAxisAlignment .'),
// )
// ],
// )
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
/**
* 寫一個矩形
*/
class Box extends StatelessWidget{
String mStr="";
Box(@required String str){
this.mStr = str;
}
@override
Widget build(BuildContext context) {
return Container(
width: 80,
height: 80,
alignment: Alignment.center,
color: Colors.teal.shade300,
child: Text(mStr),
foregroundDecoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
)
),
);
}
}
複製程式碼