文章介紹
之前寫過(guò)一篇Flutter介紹的文章,然后因?yàn)橐恍┢渌虑橥A撕镁脹](méi)寫了。這人一懶下來(lái)就懶成習(xí)慣了哈哈。這次的文章主要是介紹用Flutter實(shí)現(xiàn)一個(gè)app常用的底部tab欄,類似于安卓里面的BottomNaivigationView。有三個(gè)頁(yè)面可以點(diǎn)擊切換這樣子。
項(xiàng)目結(jié)構(gòu)

FirstTab里面的代碼:
import 'package:flutter/material.dart';
class FirstTab extends StatefulWidget {
@override
_FirstTabState createState() => _FirstTabState();
}
class _FirstTabState extends State<FirstTab> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('第一個(gè)界面'),
),
body: new Center(
child: new Text('first'),
),
);
}
}
就是一個(gè)簡(jiǎn)單的界面,一個(gè)標(biāo)題欄文本,和一個(gè)居中的文本。第二個(gè)和第三個(gè)界面也都是一樣類似的,文本不同而已。這里教大家一個(gè)小技巧,在AndroidStudio里面創(chuàng)建Widget的快捷鍵。
stful ===> 創(chuàng)建一個(gè)StatefulWidget,并且會(huì)自動(dòng)生成State,很省事
stless ===> 創(chuàng)建一個(gè)StatelessWidget
Widget生命周期
在把這三個(gè)界面整合到一起之前,我想先插入一點(diǎn)很重要的知識(shí)。在Flutter里面萬(wàn)物皆是Widget,所以我想先介紹一下Widget的生命周期。但是說(shuō)Widget的生命周期這個(gè)說(shuō)法其實(shí)是不準(zhǔn)確的。
因?yàn)閃idget分為StatefulWidget和StatelessWidget,可變的是StatefulWidget,它的可變又是通過(guò)修改State來(lái)完成的,等下在代碼里面可以看到有@override標(biāo)識(shí)的生命周期方法其實(shí)是在繼承于State的狀態(tài)類里面寫的。所以說(shuō)成是State的生命周期更加準(zhǔn)確一點(diǎn)。
| 方法名稱 | 狀態(tài) |
|---|---|
| initState | 插入渲染樹時(shí)調(diào)用,只調(diào)用一次 |
| didChangeDependencies | state依賴的對(duì)象發(fā)生變化時(shí)調(diào)用 |
| didUpdateWidget | 組件狀態(tài)改變時(shí)候調(diào)用,可能會(huì)調(diào)用多次 |
| build | 構(gòu)建Widget時(shí)調(diào)用 |
| deactivate | 當(dāng)移除渲染樹的時(shí)候調(diào)用 |
| dispose | 組件即將銷毀時(shí)調(diào)用 |
完整的生命如圖所有的方法和分階段執(zhí)行的圖解,很詳細(xì)了。圖片是從閑魚技術(shù)那里copy來(lái)的。推薦大家都關(guān)注一下閑魚技術(shù),他們確實(shí)在Flutter這一塊有很多自己的實(shí)踐文章

主入口
現(xiàn)在我們把三個(gè)頁(yè)面放到main.dart里面,做出一個(gè)類似BottomNaivigationView的效果。
首先在main.dart文件里面導(dǎo)入之前我們寫好的三個(gè)tab頁(yè)
import './pages/FirstTab.dart';
import './pages/SecondTab.dart';
import './pages/ThirdTab.dart';
我這里因?yàn)槭且呀?jīng)寫完了,就是使用過(guò)這三個(gè)了,字體不會(huì)是灰色帶波浪線的。所以大家碰到灰色帶波浪線的話也不要慌張,寫完就好了。
main.dart完整代碼:
import 'package:flutter/material.dart';
import './pages/FirstTab.dart';
import './pages/SecondTab.dart';
import './pages/ThirdTab.dart';
void main(){
runApp(
new MaterialApp(
title:'tabdemo',
home:new HomePage()
)
);
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() =>new _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin{
//Tab頁(yè)的控制器,可以用來(lái)定義Tab標(biāo)簽和內(nèi)容頁(yè)的坐標(biāo)
TabController tabcontroller;
//生命周期方法插入渲染樹時(shí)調(diào)用,只調(diào)用一次
@override
void initState() {
super.initState();
tabcontroller = new TabController(
length: 3, //Tab頁(yè)的個(gè)數(shù)
vsync: this //動(dòng)畫效果的異步處理,默認(rèn)格式
);
}
//生命周期方法構(gòu)建Widget時(shí)調(diào)用
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new TabBarView(
controller: tabcontroller,
children: <Widget>[
//創(chuàng)建之前寫好的三個(gè)頁(yè)面,萬(wàn)物皆是Widget
new FirstTab(),
new SecondTab(),
new ThirdTab(),
],
),
bottomNavigationBar: new Material(
//底部欄整體的顏色
color: Colors.blueAccent,
child: new TabBar(
controller: tabcontroller,
tabs: <Tab>[
new Tab(text: "第一個(gè)",icon: new Icon(Icons.android)),
new Tab(text: "第二個(gè)",icon: new Icon(Icons.home)),
new Tab(text: "第三個(gè)",icon: new Icon(Icons.accessibility)),
],
//tab被選中時(shí)的顏色,設(shè)置之后選中的時(shí)候,icon和text都會(huì)變色
labelColor: Colors.amber,
//tab未被選中時(shí)的顏色,設(shè)置之后選中的時(shí)候,icon和text都會(huì)變色
unselectedLabelColor: Colors.black,
),
)
);
}
//組件即將銷毀時(shí)調(diào)用
@override
void dispose() {
//釋放內(nèi)存,節(jié)省開銷
tabcontroller.dispose();
super.dispose();
}
}
1.首先main方法是主入口。title里面的標(biāo)題就是app在后臺(tái)時(shí)顯示的名字。
2.HomePage是一個(gè)有狀態(tài)的組件,通過(guò)修改_HomePageState 來(lái)修改他顯示內(nèi)容
3._HomePageState 里面有三個(gè)方法initState,build,dispose。這三個(gè)都是生命周期方法,上面表格里面有詳細(xì)描述,在這里是按照我代碼里面的順序執(zhí)行的。
4.TabController相當(dāng)于是tabbar的控制器,在build方法里面創(chuàng)建控件的時(shí)候作為參數(shù)傳入
5.build方法里面先是創(chuàng)建了一個(gè)Scaffold,然后里面放入了控件,也就是界面顯示出來(lái)的東西,類似于安卓里面的view??丶木唧w用法可參考 Widget目錄
6.最后在dispose組件銷毀的時(shí)候銷毀掉tabcontroller
運(yùn)行效果

其實(shí)實(shí)現(xiàn)的也比較簡(jiǎn)單,就是三個(gè)可以切換的頁(yè)面,既可以點(diǎn)擊切換,又可以滑動(dòng)切換。
補(bǔ)充說(shuō)明
我的代碼里面有很多new關(guān)鍵字,其實(shí)在Dart2里面這些new是可以省略掉的,但是因?yàn)槲覍慗ava寫習(xí)慣了,為了便于大家閱讀,我還是加了new的。
然后其實(shí)我現(xiàn)在也只是一個(gè)小菜雞,一些復(fù)雜的界面自己現(xiàn)在也實(shí)現(xiàn)不了,還在學(xué)習(xí)之中。后期抽空會(huì)把這三個(gè)子界面完善出來(lái),盡量實(shí)現(xiàn)一些常用的東西,比如列表,界面跳轉(zhuǎn),手勢(shì),動(dòng)畫之類的。暫時(shí)的想法是這樣。謝謝閱讀,大家周末愉快~