- Flex 彈性(流式)布局
- Wrap 包裹,自動(dòng)換行布局
- SingleChildScrollView 滾動(dòng)布局
- FittedBox 負(fù)責(zé)對(duì)組件進(jìn)行縮放和位置調(diào)整
- FractionallySizedBox 寬度和高度縮放(百分比布局)
- ConstrainedBox-限制約束或者LimitedBox(限制寬高)
- BaseLine 基線的對(duì)其方式
- Row 水平布局
- Column 垂直布局
AspectRatio調(diào)整寬高比示例
- Offstage 控制是否顯示
OverflowBox溢出父容器顯示示例
- Padding 填充布局
Table布局示例
- Transform矩陣轉(zhuǎn)換示例
1.彈性布局(Flex)
- 允許子組件按照一定比例來(lái)分配父容器空間。
- 主要通過(guò)Flex和Expanded來(lái)配合實(shí)現(xiàn)
① Flex
- Flex組件可以沿著水平或垂直方向排列子組件
-
direction
:Axis.vertical
表示垂直方向Axis.horizontal
表示水平方向 -
flex
: 彈性系數(shù)抡草,大于0會(huì)按比例來(lái)分割浮定,等于0不會(huì)擴(kuò)展占用的空間
效果圖代碼
通過(guò) Expanded
和 Flex
實(shí)現(xiàn)
import 'package:flutter/material.dart';
class FlexWidget extends StatefulWidget {
FlexWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_FlexWidgetState createState() => _FlexWidgetState();
}
class _FlexWidgetState extends State<FlexWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flex"),
),
body: Column(
children: <Widget>[
Container(
height: 400.0,
child: Flex(
direction: Axis.vertical,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.yellow,
),
),
],
),
),
Container(
height: 120.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
// 子組件的排列方式為主軸兩端對(duì)齊
children: <Widget>[
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
)),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
))
],
))
],
));
}
}
② Wrap
字面意思,包裹??
- 把具有相同點(diǎn)的布局整合在一個(gè)大的布局組件之內(nèi)
- 結(jié)局Row布局的局限:在水平位置上“撐破”了屏幕猴娩,這種情況可以使用
換行處理【W(wǎng)rap】
- 常見(jiàn)屬性
spacing : 水平方向間距
runSpacing : 垂直方向間距
效果圖
效果圖代碼
import 'package:flutter/material.dart';
class WrapWidget extends StatefulWidget {
WrapWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_WrapWidgetState createState() => _WrapWidgetState();
}
class _WrapWidgetState extends State<WrapWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Wrap"),
),
body: Column(
children: <Widget>[
Wrap(
spacing: 4.0,
runSpacing: 4.0,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
],
)
],
));
}
}
案例二
效果圖
代碼
Wrap(
spacing: 8.0, // Chip之間的間距大小
runSpacing: 4.0, // 行之間的間距大小
children: <Widget>[
Chip(
//添加圓形頭像
avatar: CircleAvatar(
backgroundColor: Colors.lightGreen.shade800, child: Text('西門(mén)', style: TextStyle(fontSize: 10.0),)),
label: Text('西門(mén)吹雪'),
),
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.lightBlue.shade700, child: Text('司空', style: TextStyle(fontSize: 10.0),)),
label: Text('司空摘星'),
),
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.orange.shade800, child: Text('婉清', style: TextStyle(fontSize: 10.0),)),
label: Text('木婉清'),
),
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.blue.shade900, child: Text('一郎', style: TextStyle(fontSize: 10.0),)),
label: Text('蕭十一郎'),
),
],
)
③SingleChildScrollView-滾動(dòng)布局
- 組件是負(fù)責(zé)滾動(dòng)的钟些,里面只能嵌套一個(gè)組件
- Column布局超出屏幕后不能滾動(dòng)墩朦,需要在外層嵌套SingleChildScrollView才可以
- 可以設(shè)置滾動(dòng)方向坯认,也可以通過(guò)reverse 屬性設(shè)置閱讀順序
- 還可以解決TextField布局溢出問(wèn)題
④FittedBox 縮放
負(fù)責(zé)對(duì)組件進(jìn)行縮放和位置調(diào)整
-
fit 縮放方式
縮放本身占據(jù)FittedBox的大小,默認(rèn)值BoxFit.contain子組件的寬度或高度被縮放到父容器限定的值時(shí),就會(huì)被停止縮放
- alignment 對(duì)齊方式
Row(
children: <Widget>[
Container(
color: Colors.blue,
width: 80.0,
height: 80.0,
margin: EdgeInsets.only(bottom: 10.0),
child: new FittedBox(
fit: BoxFit.contain,
alignment: Alignment.topLeft,
child: new Container(
color: Colors.yellow,
child: new Text("FittedBox"),
),
),
),
Text(
"BoxFit.contain",
style: new TextStyle(fontSize: 20.0),
)
],
)
⑤FractionallySizedBox 寬度和高度縮放(百分比布局)
- 基于寬度縮放因子和高度縮放因子來(lái)調(diào)整布局
- 大小有可能超出其父組件的設(shè)置
- 如果FractionallySizedBox中子組件設(shè)置了大小牛哺,則不會(huì)起作用,會(huì)被覆蓋掉
Container(
color: Colors.blue,
height: 130.0,
width: 130.0,
padding: EdgeInsets.all(5.0),
child: new FractionallySizedBox(
alignment: Alignment.topLeft,
widthFactor: 1.5,//寬度因子
heightFactor: 0.5,//高度因子
child: new Container(
color: Colors.yellow,
),
),
)
⑥ConstrainedBox-限制約束或者LimitedBox(限制寬高)
- 在其約定范圍內(nèi)陋气,其子組件是不能逾越的
- ConstrainedBox中主要是constraints起作用,而且這個(gè)值不能為null(空)
ConstrainedBox(
constraints: BoxConstraints(
minWidth: 100.0,
minHeight: 100.0,
maxWidth: 250.0,
maxHeight: 250.0,
),
child: new Container(
width: 500.0,
height: 300.0,
color: Colors.blue,
child: Text(
"100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000",
style: new TextStyle(color: Colors.black, fontSize: 20.0),
// 設(shè)置省略號(hào)
overflow: TextOverflow.ellipsis,
// 設(shè)置最大行數(shù)
maxLines: 1,
),
),
)
⑦BaseLine
- 一種基線的對(duì)其方式引润,把不相關(guān)的幾個(gè)組件設(shè)置在同一條水平線上進(jìn)行對(duì)齊
- baseline 設(shè)置位置,單位是浮點(diǎn)型(不能為空)
- baselineType 不能為空
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Baseline(
baseline: 80.0,
baselineType: TextBaseline.alphabetic,
child: new Text(
'今天天氣真好',
style: new TextStyle(
fontSize: 18.0,
color: Colors.red,
textBaseline: TextBaseline.alphabetic,
),
),
),
new Baseline(
baseline: 100.0,
baselineType: TextBaseline.alphabetic,
child: new Text(
'適合晨練',
style: new TextStyle(
fontSize: 30.0,
color: Colors.blue,
textBaseline: TextBaseline.alphabetic,
),
),
),
new Baseline(
baseline: 120.0,
baselineType: TextBaseline.alphabetic,
child: FlutterLogo(
size: 100,
),
),
],
)
⑧Row 和 Column 水平和縱向布局
-
Column
不支持滾動(dòng)巩趁,想支持滾動(dòng),需要考慮使用ListView
-
crossAxisAlignment
子組件在縱軸
的對(duì)其方式 -
mainAxisAlignment
子組件在水平方向
的對(duì)其方式 -
textDirection
布局順序淳附,從左至由晶渠,從右至左 -
mainAxisSize
max
表示盡可能多地占用水平方向位置,min
則反之
注意
- 在Row 和 Column 里CrossAxis 和 Main Axis 是不一樣的
- Row 布局 設(shè)置
crossAxisAlignment
無(wú)效 - Column 布局 設(shè)置
mainAxisAlignment
無(wú)效
Flex 案例補(bǔ)充
static var c1 = Container(
width: 50,
height: 50,
color: Colors.blue,
);
static var c2 = Container(
width: 100,
height: 80,
color: Colors.red,
);
static var c3 = Container(
width: 150,
height: 50,
color: Colors.yellow,
);
var flex_test = Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: c1,
),
Expanded(
child: c2,
),
Expanded(
child: c3,
),
],
);
⑨AspectRatio調(diào)整寬高比示例
Container(
height: 200.0,
child: AspectRatio(
aspectRatio: 1.5,//比例可以調(diào)整
child: Container(
color: Colors.green,
),
),
)
Offstage 控制是否顯示
//狀態(tài)控制是否顯示文本組件
bool offstage = true;
Center(
child: Offstage(
offstage: offstage,//控制是否顯示
child: Text(
'我出來(lái)啦燃观!',
style: TextStyle(
fontSize: 36.0,
),
),
),
)
OverflowBox溢出父容器顯示示例
效果圖
代碼
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('OverflowBox溢出父容器顯示示例'),
),
body: Container(
color: Colors.green,
width: 200.0,
height: 200.0,
padding: const EdgeInsets.all(50.0),
child: OverflowBox(
alignment: Alignment.topLeft,
maxWidth: 400.0,
maxHeight: 400.0,
child: Container(
color: Colors.blueGrey,
width: 300.0,
height: 300.0,
),
),
));
}
}
Padding 填充布局
效果圖
代碼
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Padding填充布局示例'),
),
body: Center(
//添加容器 外框
child: Container(
width: 300.0,
height: 300.0,
//容器內(nèi)邊距上下左右設(shè)置為60.0
padding: EdgeInsets.all(6.0),
//添加邊框
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.green,
width: 8.0,
),
),
//添加容器 內(nèi)框
child: Container(
width: 200.0,
height: 200.0,
//添加邊框
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.blue,
width: 8.0,
),
),
//添加圖標(biāo)
child: FlutterLogo(),
),
),
),
);
}
}
Table布局示例
效果圖
代碼
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Table布局示例'),
),
//表格居中
body: Center(
//添加表格
child: Table(
//設(shè)置表格有多少列,并且指定列寬
columnWidths: const <int, TableColumnWidth>{
//指定索引及固定列寬
0: FixedColumnWidth(100.0),
1: FixedColumnWidth(40.0),
2: FixedColumnWidth(80.0),
3: FixedColumnWidth(80.0),
},
//設(shè)置表格邊框樣式
border: TableBorder.all(color: Colors.black38, width: 2.0, style: BorderStyle.solid),
children: const <TableRow>[
//添加第一行數(shù)據(jù)
TableRow(
children: <Widget>[
Text('姓名'),
Text('性別'),
Text('年齡'),
Text('身高'),
],
),
//添加第二行數(shù)據(jù)
TableRow(
children: <Widget>[
Text('張三'),
Text('男'),
Text('26'),
Text('172'),
],
),
//添加第三行數(shù)據(jù)
TableRow(
children: <Widget>[
Text('李四'),
Text('男'),
Text('28'),
Text('178'),
],
),
],
),
),
);
}
Transform矩陣轉(zhuǎn)換示例
效果圖
代碼
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Transform矩陣轉(zhuǎn)換示例'),
),
body: Center(
//父容器 作為背景
child: Container(
//背景顏色
color: Colors.grey,
//矩陣轉(zhuǎn)換
child: Transform(
//對(duì)齊方式
alignment: Alignment.topRight,
//設(shè)置旋轉(zhuǎn)值
transform: Matrix4.rotationZ(0.3),
//被旋轉(zhuǎn)容器
child: Container(
padding: const EdgeInsets.all(8.0),
color: const Color(0xFFE8581C),
child: const Text('Transform矩陣轉(zhuǎn)換'),
),
),
),
),
);
}
}
補(bǔ)充布局案例
效果圖
代碼
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//風(fēng)景區(qū)地址部分
Widget addressContainer = Container(
padding: const EdgeInsets.all(32.0),//此部分四周間隔一定距離
//水平布局
child: Row(
children: <Widget>[
Expanded(
//垂直布局
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, //次軸即水平方向左側(cè)對(duì)齊
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 8.0),//與下面文本間隔一定距離
child: Text(
'風(fēng)景區(qū)地址',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'湖北省十堰市丹江口市',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
//圖標(biāo)
Icon(
Icons.star,
color: Colors.red[500],
),
Text('66'),
],
),
);
//構(gòu)建按鈕組中單個(gè)按鈕 參數(shù)為圖標(biāo)及文本
Column buildButtonColumn(IconData icon, String label) {
//垂直布局
return Column(
mainAxisSize: MainAxisSize.min,//垂直方向大小最小化
mainAxisAlignment: MainAxisAlignment.center,//垂直方向居中對(duì)齊
children: <Widget>[
Icon(icon, color: Colors.lightGreen[600]),//上面圖標(biāo)部分
Container(
//距離上面圖標(biāo)一定間距
margin: const EdgeInsets.only(top: 8.0),
//下面文本部分
child: Text(
label,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: Colors.lightGreen[600],
),
),
)
],
);
}
//按鈕組部分
Widget buttonsContainer = Container(
//水平布局
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,//水平方向均勻排列每個(gè)元素
children: <Widget>[
buildButtonColumn(Icons.call, '電話'),
buildButtonColumn(Icons.near_me, '導(dǎo)航'),
buildButtonColumn(Icons.share, '分享'),
],
),
);
//風(fēng)景區(qū)介紹文本部分
Widget textContainer = Container(
//設(shè)置上下左右內(nèi)邊距
padding: const EdgeInsets.all(32.0),
//文本塊一定是用'''來(lái)引用起來(lái)
child: Text(
'''
武當(dāng)山褒脯,中國(guó)道教圣地,又名太和山缆毁、謝羅山番川、參上山、仙室山脊框,古有“太岳”颁督、“玄岳”、“大岳”之稱浇雹。位于湖北西北部十堰市丹江口市境內(nèi)沉御。東接聞名古城襄陽(yáng)市,西靠車城十堰市 昭灵,南望原始森林神農(nóng)架吠裆,北臨高峽平湖 丹江口水庫(kù)。
明代烂完,武當(dāng)山被皇帝封為“大岳”试疙、“治世玄岳”,被尊為“皇室家廟”抠蚣。武當(dāng)山以“四大名山皆拱揖祝旷,五方仙岳共朝宗”的“五岳之冠”地位聞名于世。
1994年12月嘶窄,武當(dāng)山古建筑群入選《世界遺產(chǎn)名錄》怀跛,2006年被整體列為“全國(guó)重點(diǎn)文物保護(hù)單位” 。2007年柄冲,武當(dāng)山和長(zhǎng)城吻谋、麗江、周莊等景區(qū)一起入選 “歐洲人最喜愛(ài)的中國(guó)十大景區(qū)”羊初。2010至2013年滨溉,武當(dāng)山分別被評(píng)為國(guó)家5A級(jí)旅游區(qū)、國(guó)家森林公園长赞、中國(guó)十大避暑名山晦攒、海峽兩岸交流基地,入選最美 “國(guó)家地質(zhì)公園”得哆。
截至2013年脯颜,武當(dāng)山有古建筑53處,建筑面積2.7萬(wàn)平方米贩据,建筑遺址9處栋操,占地面積20多萬(wàn)平方米,全山保存各類文物5035件饱亮。
武當(dāng)山是道教名山和武當(dāng)武術(shù)的發(fā)源地矾芙,被稱為“亙古無(wú)雙勝境,天下第一仙山”近上。武當(dāng)武術(shù)剔宪,是中華武術(shù)的重要流派。元末明初壹无,道士張三豐集其大成葱绒,開(kāi)創(chuàng)武當(dāng)派。
''',
softWrap: true,
),
);
return MaterialApp(
title: '布局綜合示例',
//自定義主題斗锭,主體顏色為綠色風(fēng)格
theme: ThemeData(
brightness: Brightness.light, //應(yīng)用程序整體主題的亮度
primaryColor: Colors.lightGreen[600], //App主要部分的背景色
accentColor: Colors.orange[600], //前景色(文本地淀、按鈕等)
),
home: Scaffold(
appBar: AppBar(
//頁(yè)面標(biāo)題
title: Text(
'武當(dāng)山風(fēng)景區(qū)',
style: TextStyle(color: Colors.white),
),
),
//使用列表視圖默認(rèn)為垂直布局,并且子元素能夠上下滾動(dòng)
body: ListView(
children: <Widget>[
//風(fēng)景圖片
Image.asset(
'images/wudang.jpeg',
width: 600.0,
height: 240.0,
fit: BoxFit.cover, //圖片填充整個(gè)父容器
),
addressContainer,
buttonsContainer,
textContainer,
],
),
),
);
}
}