??????小菜今天來整理一下在學習測試 Flutter 時需用到的底部導航欄 BottomNavigationBar,使用方式很簡單脏榆,小菜感覺效果比原生的 Android 要好一些猖毫。
何為 BottomNavigationBar ?
??????BottomNavigationBar 為底部導航欄控件,可以包含文字標簽和圖標等基本信息须喂,通常在三到五個之間吁断;據(jù)了解,iOS 的規(guī)范底部導航欄最多可設置五個坞生,所以大部分應用均在五個以內(nèi)仔役;現(xiàn)在很多應用都是以底部導航欄 + 中部主內(nèi)容 Content 方式來展示。
??????官網(wǎng)建議是己,BottomNavigationBar 底部導航欄通常與 Scaffold 一起使用又兵,其中它作為Scaffold.bottomNavigationBar 參數(shù)提供。
如何應用 BottomNavigationBar ?
- 與 body 同級的位置添加 BottomNavigationBar卒废,BottomNavigationBarItem 中可以添加文字標簽或圖標 (Icons/Image) 等沛厨,若圖片不存在時會顯示空白宙地;這樣就可以添加底部狀態(tài)欄內(nèi)容,文字和圖標的樣式也可以隨意調(diào)整逆皮;如下:
bottomNavigationBar: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.category), title: new Text('簽到')),
BottomNavigationBarItem(
icon: new Icon(Icons.account_circle), title: new Text('我')),
],
),
- 只有底部狀態(tài)欄是不夠的宅粥,還需要對應的中間展示內(nèi)容塊,可以跟 Android 的思路一樣页屠,添加幾個 Page() 頁作為 Fragment粹胯,小菜因為測試內(nèi)容相對簡單蓖柔,嘗試使用了 PageView辰企,即對應 Android 中的 ViewPager,小菜會在今后的測試中詳細說明况鸣,今天主要是使用基本方法展示主模塊內(nèi)容牢贸;如下:
body: new PageView.builder(
itemBuilder: (BuildContext context, int index) {
var str =
(index == 0) ? "這里是【HomePage】->【簽到】頁面" : "這里是【HomePage】->【我】頁面";
return new Center(
child: new Container(
width: 340.0,
child: new Card(
color: Colors.blue,
elevation: 16.0,
child: new FlatButton(
child:
new Text(str, style: new TextStyle(color: Colors.white)),
)),
));
},
itemCount: 2,
),
- 此時主模塊 PageView 可以滑動切換內(nèi)容,但是對應的底部狀態(tài)欄不會變化镐捧;因為目前沒有綁定對應的點擊事件等潜索;此時需要添加 PageController 和 狀態(tài)欄的 onTap 點擊事件;如下:
int _currentIndex = 0;
var _pageController = new PageController(initialPage: 0);
void _pageChange(int index) {
if (_currentIndex != index) {
_currentIndex = index;
}
}
// 添加 PageView 的 PageController
body: new PageView.builder(
onPageChanged: _pageChange,
controller: _pageController,
itemBuilder: (BuildContext context, int index) {
...
}
),
// 添加 BottomNavigationBar 的 onTap
bottomNavigationBar: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
...
],
//設置當前的索引
currentIndex: _currentIndex,
//tabBottom的點擊監(jiān)聽
onTap: (int index) {
_pageController.animateToPage(index,
duration: new Duration(seconds: 2),
curve: new ElasticOutCurve(0.8));
_pageChange(index);
_currentIndex = index;
},
),
- 此時懂酱,點擊底部狀態(tài)欄對應的 PageView 會切換內(nèi)容竹习,但是底部狀態(tài)欄并沒有改變樣式,因為目前用的時固定的圖標和文字列牺,此時需要處理圖標和文字切換時的樣式整陌,如下:
var _bottomText = ['簽到', '我'];
var _bottomIcons = [
[
new Icon(Icons.category, color: Colors.grey),
new Icon(Icons.category, color: Colors.blue),
],
[
new Icon(Icons.account_circle, color: Colors.grey),
new Icon(Icons.account_circle, color: Colors.blue),
]
];
Icon changeIconStyle(int curIndex) {
if (curIndex == _currentIndex) {
return _bottomIcons[curIndex][1];
}
return _bottomIcons[curIndex][0];
}
Text changeTextStyle(int curIndex) {
if (curIndex == _currentIndex) {
return new Text(_bottomText[curIndex],
style: new TextStyle(color: Colors.blue));
} else {
return new Text(_bottomText[curIndex],
style: new TextStyle(color: Colors.grey));
}
}
bottomNavigationBar: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
new BottomNavigationBarItem(
icon: changeIconStyle(0), title: changeTextStyle(0)),
new BottomNavigationBarItem(
icon: changeIconStyle(1), title: changeTextStyle(1)),
],
...
),
- 然而小菜添加了更改狀態(tài)時的樣式,點擊底部狀態(tài)欄時依舊不會變色瞎领;小菜查了很久突然發(fā)現(xiàn)泌辫,小菜的 HomePage() 繼承的是 StatelessWidget 無狀態(tài)樣式,此時更換為 StatefulWidget 有狀態(tài)樣式九默,并實現(xiàn)對應方法震放;如下:
class HomePage extends StatefulWidget {
String result;
HomePage(this.result);
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
int _currentIndex = 0;
...
}
??????至此,底部狀態(tài)欄 BottomNavigationBar 配合滑動 PageView 的基本功能已經(jīng)完成驼修。
實用小貼士
- 通過點擊 BottomNavigationBar 對 PageView 切換過程中殿遂,可以設置動畫過程,也可以直接跳轉(zhuǎn)到對應頁面乙各,需要設置 animateToPage 或 jumpToPage墨礁;如下:
onTap: (int index) {
// 切換時沒有動畫效果
// _pageController.jumpToPage(index);
// 切換時添加動畫效果
_pageController.animateToPage(index,
duration: new Duration(seconds: 2),
curve: new ElasticOutCurve(0.8));
_pageChange(index);
_currentIndex = index;
},
- BottomNavigationBar 有兩種樣式分別為 shifting 和 fixed;直接效果圖觅丰,shifting 樣式時會突出顯示選中的 item饵溅,其他的 item 文字隱藏;fixed 樣式均分妇萄,沒有突出效果蜕企;如下:
type: BottomNavigationBarType.shifting,
shifting
shifting
type: BottomNavigationBarType.fixed,
fixed
fixed
??????GitHub Demo
??????小菜剛接觸 Flutter 時間不長咬荷,還有很多不清楚和不理解的地方,如果又不對的地方還希望多多指出轻掩。
來源:阿策小和尚