Flutter | 使用BottomNavigationBar快速構(gòu)建底部導(dǎo)航

前言

Google推出flutter這樣一個新的高性能跨平臺(Android夏跷,ios)快速開發(fā)框架之后,被業(yè)界許多開發(fā)者所關(guān)注明未。我在接觸了flutter之后發(fā)現(xiàn)這個確實是一個好東西槽华,好東西當(dāng)然要和大家分享,對吧亚隅。

今天要跟大家分享的是底部導(dǎo)航功能的實現(xiàn)硼莽。我認(rèn)為flutter的就是在傳達(dá)一種最簡設(shè)計庶溶,一個部件只關(guān)注它本身煮纵,達(dá)到低耦合高內(nèi)聚。所以本文講解底部導(dǎo)航將只關(guān)注該功能的實現(xiàn)偏螺,并對布局思路進(jìn)行介紹行疏。

你將學(xué)到什么

  • 如何將部件拆分
  • 如何構(gòu)建flutter布局
  • 如何創(chuàng)建底部導(dǎo)航

首先讓大家看看效果。

image

這是一個最簡單的底部導(dǎo)航案例套像,我不希望引入過多其他東西酿联,把初學(xué)者的腦子搞得很亂(這也是我在學(xué)習(xí)中所遇到的)。

建立布局

第一步:繪制布局視圖

將布局分解為基本元素:

  • 頁面是由哪些元素構(gòu)成的
  • 哪些控件會因為用戶的交互而發(fā)生變化夺巩,哪些不會
image

在這個應(yīng)用中我們期望能夠通過點(diǎn)擊底部導(dǎo)航欄就能切換上面的整個頁面贞让。這個行為觸發(fā)了頁面的刷新。

這里我們需要思考一個問題柳譬,刷新的范圍在哪里喳张?

用過手機(jī)app的同學(xué)都知道,我們可以點(diǎn)擊底部導(dǎo)航欄美澳,底部是不會刷新的销部,而刷新的只有上面部分摸航。所以我們可以把整個頁面拆成兩部分。

第一個部分是橘色框里的頁面部分舅桩,第二個部分是我們底部的導(dǎo)航器部分酱虎。而導(dǎo)航器是一直不變的,所以導(dǎo)航器應(yīng)該是在它們之中處于父級widget層次擂涛。

第二步:開始構(gòu)造底部導(dǎo)航


class BottomNavigationWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => BottomNavigationWidgetState();
}

class BottomNavigationWidgetState extends State<BottomNavigationWidget> {
  final _bottomNavigationColor = Colors.blue;
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: Icon(
                Icons.home,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'HOME',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.email,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'Email',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.pages,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'PAGES',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.airplay,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'AIRPLAY',
                style: TextStyle(color: _bottomNavigationColor),
              )),
        ],
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
} 

我們這里使用了Scaffold布局读串,它默認(rèn)提供了一個bottomNavigationBar的屬性,我們在這里給它一個BottomNavigationBar,并在這個BottomNavigationBar中放了四個BottomNavigationBarItem(一下簡稱item)歼指。每個item就是底部的一個導(dǎo)航按鈕爹土。

BottomNavigationBar的items是一個數(shù)組,那么就會存在下標(biāo)踩身。BottomNavigationBar為我們提供了一個currentIndex屬性胀茵,默認(rèn)是0,我們進(jìn)去看看這個方法。

 /// The index into [items] of the current active item.
  final int currentIndex;

currentIndex代表了當(dāng)前再items中被選中的index挟阻。

BottomNavigationBar還提供了一個onTap方法琼娘。我們再看看這個方法。

  /// The callback that is called when a item is tapped.
  /// The widget creating the bottom navigation bar needs to keep track of the
  /// current index and call `setState` to rebuild it with the newly provided
  /// index.
  final ValueChanged<int> onTap;

當(dāng)?shù)撞繉?dǎo)航的一個item被點(diǎn)擊時附鸽,它會調(diào)用此方法脱拼,并傳入當(dāng)前item的index值,這樣就能改變焦點(diǎn)到當(dāng)前的index上的item了坷备。

我們來看看效果:

image

創(chuàng)建切換頁面

然后我們需要分別創(chuàng)建四個頁面熄浓,對映四個item,由于四個頁面極為相似這里只放一個省撑。建議大家對這四個頁面分別創(chuàng)建一個dart文件赌蔑。

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HOME'),
      ),
    );
  }
}

每個頁面都是一個Scaffold布局,有一個appBar竟秫。

將頁面顯示在界面上

我們再回到底部導(dǎo)航這個控件中娃惯。
由于我們是通過currentIndex這個變量來控制跳轉(zhuǎn)的,頁面要想同步也必須依賴于這個變量肥败。這里我們使用一個List<Widget>來與items對應(yīng)趾浅。

List<Widget> pages = List<Widget>();
  final _bottomNavigationBarItemColor = Colors.teal;
  int _currentIndex = 0;

  @override
  void initState() {
    pages
      ..add(HomeScreen())
      ..add(EmailScreen())
      ..add(AlarmsScreen())
      ..add(ProfileScreen());
  }

然后讓我們的BottomNavigation的Scaffold布局中body部分為List中的頁面。

body: pages[_bottomNavigationIndex],

我們讓_currentIndex來控制我們到底再body這個位置上顯示哪個頁面馒稍。這樣就能夠通過Tap我們的bottomNavigationItem來達(dá)到控制頁面跳轉(zhuǎn)的作用啦皿哨。

相關(guān)鏈接:

完整代碼:
https://github.com/Vadaski/Vadaski-flutter_note_book/tree/master/mecury_project/example/flutter_bottomnavigationbar

Youtube教學(xué)視頻:
https://www.youtube.com/watch?v=iYDaC2ESCkg&t=1221s

bilibili教學(xué)視頻:
https://www.bilibili.com/video/av28014369

寫在最后

如果各位還在flutter項目中遇到了底部導(dǎo)航問題,歡迎在下方評論區(qū)留言或者給我發(fā)送郵件 1652219550a@gmail.com 我會很樂意解答您的問題纽谒!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末证膨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子佛舱,更是在濱河造成了極大的恐慌椎例,老刑警劉巖挨决,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異订歪,居然都是意外死亡脖祈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門刷晋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盖高,“玉大人,你說我怎么就攤上這事眼虱∮靼拢” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵捏悬,是天一觀的道長撞蚕。 經(jīng)常有香客問我,道長过牙,這世上最難降的妖魔是什么甥厦? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮寇钉,結(jié)果婚禮上刀疙,老公的妹妹穿的比我還像新娘。我一直安慰自己扫倡,他們只是感情好谦秧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撵溃,像睡著了一般疚鲤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上征懈,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天石咬,我揣著相機(jī)與錄音揩悄,去河邊找鬼卖哎。 笑死,一個胖子當(dāng)著我的面吹牛删性,可吹牛的內(nèi)容都是我干的亏娜。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蹬挺,長吁一口氣:“原來是場噩夢啊……” “哼维贺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巴帮,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤溯泣,失蹤者是張志新(化名)和其女友劉穎虐秋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垃沦,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡客给,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了肢簿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片靶剑。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖池充,靈堂內(nèi)的尸體忽然破棺而出桩引,到底是詐尸還是另有隱情,我是刑警寧澤收夸,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布坑匠,位于F島的核電站,受9級特大地震影響卧惜,放射性物質(zhì)發(fā)生泄漏笛辟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一序苏、第九天 我趴在偏房一處隱蔽的房頂上張望手幢。 院中可真熱鬧,春花似錦忱详、人聲如沸围来。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽监透。三九已至,卻和暖如春航唆,著一層夾襖步出監(jiān)牢的瞬間胀蛮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工糯钙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粪狼,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓任岸,卻偏偏與公主長得像再榄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子享潜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容