Flutter的控件
Flutter提供的控件非常多,都可以在Flutter Widget 索引中進(jìn)行查看。
對(duì)于Flutter而言,所有可見(jiàn)的都是Widget。即使一個(gè)全新的頁(yè)面,也是一個(gè)Widget。沒(méi)有Android中的Activity,它和IOS有些類似,對(duì)于IOS而言,所有的東西都是ViewController。
Flutter中布局的構(gòu)建,基本都是通過(guò)Row、Column來(lái)實(shí)現(xiàn)的。思想也就類似于H5中的Div。
- Row/Column:實(shí)現(xiàn)頁(yè)面中的一塊控件
- Container:控制控件的內(nèi)外邊距
- Expanded:實(shí)現(xiàn)類似于Flex的功能,用來(lái)分配控件空間
如何布局
- 找出行和列.
- 布局包含網(wǎng)格嗎?
- 有重疊的元素嗎?
- 是否需要選項(xiàng)卡?
- 注意需要對(duì)齊、填充和邊框的區(qū)域.
Flutter很大的問(wèn)題就在于一旦頁(yè)面比較復(fù)雜,小控件較多的話,嵌套層級(jí)會(huì)非常深,所以Flutter官方推薦將子控件通過(guò)函數(shù)返回,或者創(chuàng)建一個(gè)Widget類來(lái)實(shí)現(xiàn)該模塊
布局的主方向
對(duì)于Row而言,Horizontal為主軸,而Vertical為橫軸
對(duì)于Column而言,Vertical為主軸,而Horizontal為橫軸

Column+Row實(shí)現(xiàn)復(fù)雜布局
通過(guò)Raw+Column可以實(shí)現(xiàn)卡片里通用的上下、左右的布局。

其中:
- 通過(guò)
Container的padding屬性來(lái)設(shè)置EdgeInsets外邊距,如果需要實(shí)現(xiàn)內(nèi)邊距,則可以使用margin屬性
Container - 當(dāng)需要圓角的時(shí)候,可以在
Container的decoration中設(shè)置BoxDecoration來(lái)添加,在BoxDecoration.borderRadius屬性中設(shè)置圓角 - 通過(guò)
Expanded來(lái)實(shí)現(xiàn)H5中Flex的布局,或者說(shuō)Android中的Weight來(lái)分配Widget剩余的空間 - 通過(guò)
crossAxisAlignment來(lái)設(shè)置Android中的Gravity也就是內(nèi)容的位置
控件實(shí)現(xiàn):
class TitleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(32.0), // 設(shè)置邊距,上下左右全為32
child: new Row(
children: [
new Expanded( //上下文本的Widget
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start, // 從Widget的開(kāi)始處繪制內(nèi)容
children: [
new Container(
padding: const EdgeInsets.only(bottom: 8.0), // 控制文本的外邊距為底部8像素
child: new Text(
'Oeschinen Lake Campground',
style: new TextStyle(
fontWeight: FontWeight.bold, // 設(shè)置字體為粗體
),
),
),
new Text(
'Kandersteg, Switzerland',
style: new TextStyle(
color: Colors.grey[500], // 設(shè)置字體顏色為灰色
),
),
],
),
),
new Icon(
Icons.star, // 設(shè)置icon
color: Colors.red[500], // 設(shè)置圖標(biāo)顏色為紅色
),
new Text('41'),
],
),
);
}
}
如果在
Raw中設(shè)置mainAxisAlignment: MainAxisAlignment.spaceEvenly,則代表將控件空間平均分給子控件,但是如果子控件中有Expanded,那會(huì)以Expanded子控件為主,mainAxisAlignment則不會(huì)生效
調(diào)整Widget的大小
如果有如下圖所示的情況,中間的控件或者其他控件需要占據(jù)不同的比例分配空間,則可以使用flex屬性,來(lái)進(jìn)行空間分配。

默認(rèn)每個(gè)子widget的
flex都是1,當(dāng)有不為1的情況出現(xiàn),則會(huì)根據(jù)flex之和,再按比例分配子控件空間。
body: new Center(
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new Expanded(
child: new Image.asset('images/pic1.jpg'),
),
new Expanded(
flex: 2,
child: new Image.asset('images/pic2.jpg'),
),
new Expanded(
child: new Image.asset('images/pic3.jpg'),
),
)
)
控件層疊Stack
在Android中可以使用FrameLayout來(lái)層疊控件,而在Flutter中,則是通過(guò)Stack來(lái)實(shí)現(xiàn)。

相關(guān)實(shí)現(xiàn):
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var stack = new Stack( // 創(chuàng)建Stack Widget
alignment: const Alignment(0.6, 0.6),
children: [
new CircleAvatar( // 圓形頭像的控件
backgroundImage: new AssetImage('images/pic.jpg'), // 圖片
radius: 100.0, // 圖片的圓角
),
new Container(
decoration: new BoxDecoration(
color: Colors.black45, // Container的背景色
),
child: new Text(
'Mia B',
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
);
// ...
}
}
