Flutter 底部導航——BottomNavigationBar | 掘金技術徵文

Vadaski發表於2018-07-29

前言

Google推出flutter這樣一個新的高效能跨平臺(Android,ios)快速開發框架之後,被業界許多開發者所關注。我在接觸了flutter之後發現這個確實是一個好東西,好東西當然要和大家分享,對吧。

今天要跟大家分享的是底部導航功能的實現。我認為flutter的就是在傳達一種最簡設計,一個部件只關注它本身,達到低耦合高內聚。所以本文講解底部導航將只關注該功能的實現,並對佈局思路進行介紹。

你將學到什麼

  • 如何將部件拆分
  • 如何構建flutter佈局
  • 如何建立底部導航

首先讓大家看看效果。

Flutter 底部導航——BottomNavigationBar | 掘金技術徵文
這是一個最簡單的底部導航案例,我不希望引入過多其他東西,把初學者的腦子搞得很亂(這也是我在學習中所遇到的)。

建立佈局

第一步:繪製佈局檢視

將佈局分解為基本元素:

  • 頁面是由哪些元素構成的
  • 哪些控制元件會因為使用者的互動而發生變化,哪些不會

Flutter 底部導航——BottomNavigationBar | 掘金技術徵文
在這個應用中我們期望能夠通過點選底部導航欄就能切換上面的整個頁面。這個行為觸發了頁面的重新整理。

這裡我們需要思考一個問題,重新整理的範圍在哪裡?

用過手機app的同學都知道,我們可以點選底部導航欄,底部是不會重新整理的,而重新整理的只有上面部分。所以我們可以把整個頁面拆成兩部分。

第一個部分是橘色框裡的頁面部分,第二個部分是我們底部的導航器部分。而導航器是一直不變的,所以導航器應該是在它們之中處於父級widget層次。

第二步:開始構造底部導航


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佈局,它預設提供了一個bottomNavigationBar的屬性,我們在這裡給它一個BottomNavigationBar,並在這個BottomNavigationBar中放了四個BottomNavigationBarItem(一下簡稱item)。每個item就是底部的一個導航按鈕。

BottomNavigationBar的items是一個陣列,那麼就會存在下標。BottomNavigationBar為我們提供了一個currentIndex屬性,預設是0,我們進去看看這個方法。

 /// The index into [items] of the current active item.
  final int currentIndex;
複製程式碼

currentIndex代表了當前再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;
複製程式碼

當底部導航的一個item被點選時,它會呼叫此方法,並傳入當前item的index值,這樣就能改變焦點到當前的index上的item了。

我們來看看效果:

Flutter 底部導航——BottomNavigationBar | 掘金技術徵文

建立切換頁面

然後我們需要分別建立四個頁面,對映四個item,由於四個頁面極為相似這裡只放一個。建議大家對這四個頁面分別建立一個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。

將頁面顯示在介面上

我們再回到底部導航這個控制元件中。 由於我們是通過currentIndex這個變數來控制跳轉的,頁面要想同步也必須依賴於這個變數。這裡我們使用一個List來與items對應。

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來達到控制頁面跳轉的作用啦。

相關連結:

完整程式碼: github.com/Vadaski/Vad…

Youtube教學視訊: www.youtube.com/watch?v=iYD…

bilibili教學視訊: www.bilibili.com/video/av280…

之後將持續分享一些flutter經驗,有任何問題的話歡迎回復,我會很快更新的!

從 0 到 1:我的 Flutter 技術實踐 | 掘金技術徵文,徵文活動正在進行中

相關文章