Flutter最基礎(chǔ)的組件類是Widget,其它所有組件都繼承Widget的,緊接著下面有兩大類組件: 有狀態(tài)組件 及 無狀態(tài)組件 。有狀態(tài)組件是界面會(huì)發(fā)生變化的組件,無狀態(tài)組件即界面不會(huì)發(fā)生變化的組件;

無狀態(tài)組件:StatelessWidget
無狀態(tài)組件(StatelessWidget)是不可變的,這意味著它們的屬性是不可以改變的,所有的值都是最終的;
有狀態(tài)組件:StatefulWidget
有狀態(tài)組件(StatefulWidget)持有的狀態(tài)可能在Widget生命周期中發(fā)生變化。
實(shí)現(xiàn)一個(gè)StatefulWidget至少需要兩個(gè)類:
- 一個(gè)StatefulWidget類。
- 一個(gè)是State類。
StatefulWidget類本身是不變的,但是State類在Widget生命周期中始終存在。要想讓界面發(fā)生變化,就要使用state對(duì)象,state要繼承與StatefulWidget。StatefulWidget是描述外觀的,而state管理最終顯示的外觀,數(shù)據(jù)的變化,當(dāng)數(shù)據(jù)發(fā)生變化之后通過setState 重新渲染界面
因?yàn)門abBar的狀態(tài)是會(huì)變的,所以實(shí)現(xiàn)TabBar的時(shí)候選用StatefulWidget,如下代碼仿微信的布局方式寫的:
import 'package:flutter/material.dart';
import 'package:wechat_demo/pages/chat_page.dart';
import 'package:wechat_demo/pages/discover_page.dart';
import 'package:wechat_demo/pages/friends_page.dart';
import 'package:wechat_demo/pages/mine_page.dart';
class RootPage extends StatefulWidget {
@override
_RootPageState createState() => _RootPageState();
}
class _RootPageState extends State<RootPage> {
//界面數(shù)組
List<Widget> pages = [
ChatPage(),
FriendsPage(),
DiscoverPage(),
MinePage()
];
int _currentIndex = 2;
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
bottomNavigationBar: BottomNavigationBar(
onTap: (int index){
_currentIndex = index;
setState(() {});
},
selectedFontSize: 12.0, //設(shè)置選中的字體大小
type: BottomNavigationBarType.fixed,
fixedColor: Colors.green,
currentIndex: _currentIndex,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_chat.png')), //未選中時(shí)的圖標(biāo)
activeIcon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_chat_hl.png')), //選中時(shí)的圖標(biāo)
title: Text('微信')
),
BottomNavigationBarItem(
icon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_friends.png')),
activeIcon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_friends_hl.png')),
title: Text('通訊錄')
),
BottomNavigationBarItem(
icon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_discover.png')),
activeIcon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_discover_hl.png')),
title: Text('發(fā)現(xiàn)')
),
BottomNavigationBarItem(
icon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_mine.png')),
activeIcon: Image(height: 20,width: 20, image: AssetImage('images/tabbar_mine_hl.png')),
title: Text('我')
)
]
),
body: pages[_currentIndex],
),
);
}
}
這里介紹幾個(gè)關(guān)鍵的組件
1、Scaffold(腳手架組件)
Scaffold實(shí)現(xiàn)了基本的Material Design布局。只要是在Material Design中定義過的單個(gè)界面顯示的布局組件元素,都可以使用Scaffold來繪制。
Scaffold常見的屬性如下表:
| 屬性名 | 類型 | 說明 |
|---|---|---|
| APPBar | AppBar | 顯示在界面頂部的一個(gè)AppBar |
| body | Widget | 當(dāng)前界面所顯示的主要內(nèi)容 |
| floatingActionButton | Widget | 在Material Design中定義的一個(gè)功能按鈕 |
| persistentFooterButtons | List<Widget> | 固定在下方顯示的按鈕 |
| drawer | Widget | 側(cè)邊欄組件 |
| bottomNavgationBar | Widget | 顯示在底部的導(dǎo)航欄按鈕欄 |
| backgroundColor | Color | 背景顏色 |
| resizeToAvoidBottomPadding | bool | 控制界面內(nèi)容body是否重新布局來避免底部被覆蓋,比如鍵盤顯示時(shí) |
2、BottomNavgationBar(底部導(dǎo)航條組件)
BottomNavgationBar是底部導(dǎo)航條,類似于iOS中的TabbarController,可以很容易的再tab之間切換,大部分APP都采用這種布局方式。
BottomNavgationBar的常見屬性如下表:
| 屬性名 | 類型 | 說明 |
|---|---|---|
| currentIndex | int | 當(dāng)前索引,用來切換按鈕控制 |
| fixedColor | Color | 選中按鈕的顏色。如果沒有指定值,則用系統(tǒng)主題色 |
| iconSize | double | 按鈕圖標(biāo)大小 |
| items | List<BottomNavgationBarItem> | 底部導(dǎo)航條按鈕集,每一項(xiàng)是一個(gè)BottomNavgationBarItem,有icon圖標(biāo)及title文本屬性 |
| onTap | ValueChanged<int> | 按下其中某個(gè)按鈕的回調(diào)事件。需要根據(jù)返回的索引設(shè)置當(dāng)前的索引 |