由上面的架構(gòu)圖可以看出來,flutter最上層是google 的紙墨設(shè)計(jì)Material Design(MaterialApp)組件芭届,關(guān)于Material Design設(shè)計(jì)理念大家可以去官網(wǎng)安利一下啊material.io
在MaterialApp下面是所有組件的基類Widget蛔钙,而在Widget的上層是statelessWdiget(無(wú)狀態(tài)組件)锌云、statefulWidget(有狀態(tài)組件)和InheritedWidget(可以向子類View樹種傳遞信息),包括我們?cè)谏掀恼轮杏玫降腟caffold吁脱、Center桑涎、Text都是statelessWdiget、statefulWidget的子類兼贡。
開始之前攻冷,我們需要知道一些名詞的含義和作用,在這里不懂的也沒有關(guān)系遍希,逐漸往后面看等曼,往后面使用后,會(huì)有越來越清晰的理解孵班。
-
MaterialApp
是我們app開發(fā)中常用的符合MaterialApp Design設(shè)計(jì)理念的入口Widget涉兽。
-
StatelessWidget
StatelessWidget是非動(dòng)態(tài)的,它不依賴于除了傳入數(shù)據(jù)以外的任何其他數(shù)據(jù)篙程,這意味著改變其顯示的唯一方式枷畏,就是改變傳入其構(gòu)造函數(shù)的參數(shù)。比如Text虱饿,Button拥诡,Icon這些控件。
-
StatefulWidget
StatefulWidget是動(dòng)態(tài)的氮发,他們?cè)试S我們創(chuàng)建一個(gè)能動(dòng)隨時(shí)間改變內(nèi)容的widget渴肉,并且不依賴于其初始化時(shí)被傳入的靜態(tài)狀態(tài),可以隨著用戶的輸入爽冕,各種形式的異步回包或其他形式的狀態(tài)變化而變化仇祭。比如Image,CheckBox颈畸,F(xiàn)orm這些控件乌奇。
-
Scaffold
Scaffold 翻譯過來就是腳手架的意思没讲,它實(shí)現(xiàn)了基本的 Material Design 可視化布局結(jié)構(gòu)。簡(jiǎn)單的說礁苗,Scaffold就是一個(gè)提供 Material Design 設(shè)計(jì)中基本布局的 widget爬凑。
const Scaffold({
Key key,
this.appBar, // 標(biāo)題欄
this.body, // 用于顯示當(dāng)前界面主要內(nèi)容的Widget
this.floatingActionButton, // 一個(gè)懸浮在body上的按鈕,默認(rèn)顯示在右下角
this.floatingActionButtonLocation, // 用于設(shè)置floatingActionButton顯示的位置
this.floatingActionButtonAnimator, // floatingActionButton移動(dòng)到一個(gè)新的位置時(shí)的動(dòng)畫
this.persistentFooterButtons, // 多狀態(tài)按鈕
this.drawer, // 左側(cè)的抽屜菜單
this.endDrawer, // 右'側(cè)的抽屜菜單
this.bottomNavigationBar,// 底部導(dǎo)航欄试伙。
this.bottomSheet, // 顯示在底部的工具欄
this.backgroundColor,// 內(nèi)容的背景顏色
this.resizeToAvoidBottomPadding = true, // 控制界面內(nèi)容 body 是否重新布局來避免底部被覆蓋嘁信,比如當(dāng)鍵盤顯示的時(shí)候,重新布局避免被鍵盤蓋住內(nèi)容疏叨。
this.primary = true,// Scaffold是否顯示在頁(yè)面的頂部
})
一個(gè) MaterialApp 由多個(gè) Scalfold 頁(yè)面組成潘靖,每個(gè) Scalfold 的主要結(jié)構(gòu)如下:
AppBar:頂部導(dǎo)航欄
body:中間內(nèi)容體
BottomNavigationBar:底部導(dǎo)航欄
-
Container
它是一個(gè)結(jié)合了繪制(painting)、定位(positioning)以及尺寸(sizing)widget的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,
})
alignment:控制child的對(duì)齊方式
decoration:繪制在child后面的裝飾
-
padding/margin
控件加入內(nèi)/外邊距秘豹。屬性如下:
EdgeInsets.all(12),// 指定四個(gè)方向相同的值
EdgeInsets.fromLTRB(10, 20, 30, 40),// 分別指定四個(gè)方向的值
EdgeInsets.only(left: 10,right: 30),// 指定任意個(gè)方向的值EdgeInsets.symmetric(vertical: 10,horizontal: 50),//指定水平(left right)或垂直方向(top,bottom)的值昌粤。
-
線性布局Row既绕、Column
Row和Column分別是Flutter中的水平和垂直布局,對(duì)應(yīng)Android里面的LinearLayout的水平垂直方向布局涮坐。
MainAxisAlignment (主軸)屬性:
enum MainAxisAlignment {
//將子控件放在主軸的開始位置
start,
//將子控件放在主軸的結(jié)束位置
end,
//將子控件放在主軸的中間位置
center,
//將主軸空白位置進(jìn)行均分凄贩,排列子元素,手尾沒有空隙
spaceBetween,
//將主軸空白區(qū)域均分袱讹,使中間各個(gè)子控件間距相等疲扎,首尾子控件間距為中間子控件間距的一半
spaceAround,
//將主軸空白區(qū)域均分,使各個(gè)子控件間距相等
spaceEvenly,
}
CrossAxisAlignment(交叉軸)屬性:
enum CrossAxisAlignment {
//將子控件放在交叉軸的起始位置
start,
//將子控件放在交叉軸的結(jié)束位置
end,
//將子控件放在交叉軸的中間位置
center,
//使子控件填滿交叉軸
stretch,
//將子控件放在交叉軸的上捷雕,并且與基線相匹配(不常用)
baseline,
}
配合Expanded使用椒丧,使Expanded中的child充滿空白區(qū)域。Expanded組件必須用在Row救巷、Column壶熏、Flex內(nèi)。
Expanded(
flex: 1,
child: Text(""),
)
屬性:
crossAxisAlignment:交叉軸子組件對(duì)齊方式
mainAxisAlignment:主軸子組件排列方式
mainAxisSize:Main 軸大小浦译,相當(dāng)于match_parent,wrap_content
verticalDirection:從下向上或從上向下擺放子組件
效果:
-
相對(duì)布局Stack
Stack 這個(gè)是Flutter中布局用到的組件棒假,跟Android中FrameLayout或RelativeLayout很像。是一個(gè)在布局中使用相當(dāng)頻繁的布局組件精盅,相當(dāng)重要的一個(gè)布局帽哑,這里當(dāng)然要著重講解。
Stack({
Key key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
- alignment : 指的是子Widget的對(duì)其方式叹俏,子view從哪個(gè)方位開始對(duì)齊
- fit :用來決定沒有Positioned方式時(shí)候子Widget的大小妻枕,StackFit.loose 指的是子Widget 多大就多大,StackFit.expand使子Widget的大小和父組件一樣大
- overflow :指子Widget 超出Stack時(shí)候如何顯示,默認(rèn)值是Overflow.clip佳头,子Widget超出Stack會(huì)被截?cái)嘤ス螅琌verflow.visible超出部分還會(huì)顯示的
- Positioned:
這個(gè)使用控制Widget的位置晴氨,通過他可以隨意擺放一個(gè)組件康嘉,有點(diǎn)像絕對(duì)布局
Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
- 配合Align使用,可以單獨(dú)設(shè)置子Widget的布局方位籽前。
Stack(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text("你創(chuàng)作的亭珍,就是頭條", style: TextStyle(fontSize: 15))
)
]