Flutter 底部導航欄bottomNavigationBar

實現一個底部導航欄,包含3到4個功能標籤,點擊對應的導航標籤能夠切換到對應的頁面內容,而且頁面擡頭顯示的內容也會跟着改變。
實際上因爲手機屏幕大小的限制,底部導航欄的功能標籤通常在3到5個左右,若是太多,會比較擁擠,影響用戶體驗,實際上目前市面上大多數APP的底部導航標籤都控制在4到5個左右。既美觀、又不會讓用戶以爲功能繁雜。這個功能的實現須要用到flutter裏的BottonNavigationBar這個控件。
屬性名 類型 說明
currentIndex int 當前索引,用來切換按鈕控制
fixedColor Color 選中按鈕的顏色,若是沒有指定值,則用系統主題色
iconSize double 按鈕圖標大小
items List<BottomNavigationBarItem> 底部導航條按鈕集。每一項是一個BottomNavigationBarItem,有icon圖標及title屬性
onTap ValueChanged<int> 按下其中某一個按鈕回調事件,須要根據返回的索引設置當前索引
首先咱們新建一個底部導航控件,因爲點擊導航標籤的時候頁面內容是會發生改變的,因此這是一個有狀態的控件。
import 'package:flutter/material.dart';
import './home.dart';
import './contacts.dart';
import './me.dart';

// 應用頁面使用有狀態Widget
class App extends StatefulWidget {
  @override
  AppState createState() => AppState();
}
//應用頁面狀態實現類
class AppState extends State<App> {
  //當前選中頁面索引
  var _currentIndex = 0;
  //聊天頁面
  HomePage home;
  //好友頁面
  Contacts contacts;
  //個人頁面
  Personal me;

  //根據當前索引返回不一樣的頁面
  currentPage(){
    switch(_currentIndex) {
      case 0:
        //返回聊天頁面
        if(home == null) {
          home = new HomePage();
        }
        return home;
      case 1:
        //返回好友頁面
        if(contacts == null) {
          contacts = new Contacts();
        }
        return contacts;
      case 2:
        //返回個人頁面
        if(me == null) {
          me = new Personal();
        }
        return me;
    }
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(

      //底部導航按鈕
      bottomNavigationBar: new BottomNavigationBar(
        //經過fixedColor設置選中item的顏色
        fixedColor:Colors.red,
        type: BottomNavigationBarType.fixed,
        //當前頁面索引
        currentIndex: _currentIndex,
        //按下後設置當前頁面索引
        onTap: ((index){
          setState(() {
            _currentIndex = index;
          });
        }),
        //底部導航按鈕項
        items: [
          //導航按鈕項傳入文本及圖標
          new BottomNavigationBarItem(
            title: new Text(
              '聊天',
              style: TextStyle(
                color: _currentIndex == 0 ? Color(0xFFF54343) : Color(0xff999999) //0x 後面開始 兩位FF表示透明度16進制 後面是顏色
              ),
            ),
            //判斷固然索引作圖片切換顯示
            icon: _currentIndex == 0 
              ? Image.asset(
                'images/nav-icon-index.active.png',
                width: 32.0,
                height: 32.0,
              ) 
              : Image.asset(
                'images/nav-icon-index.png',
                width: 32.0,
                height: 32.0,
              )
          ),
          new BottomNavigationBarItem(
            title: new Text(
              '好友',
              style: TextStyle(
                color: _currentIndex == 1 ? Color(0xFFF54343) : Color(0xff999999)
              ),
            ),
            //判斷固然索引作圖片切換顯示
            icon: _currentIndex == 1 
              ? Image.asset(
                'images/nav-icon-cat.active.png',
                width: 32.0,
                height: 32.0,
              ) 
              : Image.asset(
                'images/nav-icon-cat.png',
                width: 32.0,
                height: 32.0,
              )
          ),
          new BottomNavigationBarItem(
            title: new Text(
              '個人',
              style: TextStyle(
                color: _currentIndex == 2 ? Color(0xFFF54343) : Color(0xff999999)
              ),
            ),
            //判斷固然索引作圖片切換顯示
            icon: _currentIndex == 2 
              ? Image.asset(
                'images/nav-icon-user.active.png',
                width: 32.0,
                height: 32.0,
              ) 
              : Image.asset(
                'images/nav-icon-user.png',
                width: 32.0,
                height: 32.0,
              )
          ),
        ],
      ),

      //中間顯示當前頁面
      body: currentPage(),

    );
  }
}
fixedColor設置選中的顏色,下面能夠不單獨寫color。
 

新建三個dart文件,分別用於新建3個主體展現頁面,這三個頁面都是帶一個appbar和body,appbar用於顯示對應的導航標籤,body裏顯示標籤大圖標。三個文件的寫法基本是一致的。編程

import 'package:flutter/material.dart';

class Personal extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return new PersonalState();
  }
}

class PersonalState extends State<Personal>{
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('個人'),
      ),
      body: new Center(
        child: Icon(Icons.mood,size: 130.0,color: Colors.blue,),
      ),
    );
  }
}

 另一種實現方法,從新initState()方法:app

List<Widget> blist = List();
 @override
 void initState(){
    blist
      ..add(HomePage())
      ..add(Contacts())
      ..add(Personal());
    super.initState();
  }

這裏的..add()是Dart語言的..語法,若是你學過編程模式,你必定據說過建造者模式,簡單來講就是返回調用者自己。這裏list後用了..add(),還會返回list,而後就一直使用..語法,能一直想list裏增長widget元素。 最後咱們調用了一些父類的initState()方法。ide

完整代碼:ui

import 'package:flutter/material.dart';
import './home.dart';
import './contacts.dart';
import './me.dart';

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp>  {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('底部導航示例')),
      body: BottomNavigationWidget(),
    );
  }
}

class BottomNavigationWidget extends StatefulWidget {

  _BottomNavigationWidgetState createState() => _BottomNavigationWidgetState();
}

class _BottomNavigationWidgetState extends State<BottomNavigationWidget> {
  final _BottomNavigationColor = Colors.red;
  int _currentIndex = 0;
  List<Widget> blist = List();

  @override
  void initState(){
    blist
      ..add(HomePage()) //建造者模式,簡單來講就是返回調用者自己。這裏blist後用了..add(),還會返回blist
      ..add(Contacts())
      ..add(Personal());
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
       bottomNavigationBar:BottomNavigationBar(
         items: [
           BottomNavigationBarItem(
            icon: Icon(Icons.home,color: _BottomNavigationColor,),
            title:Text('Hmoe',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),) 
           ),
         ],
         currentIndex: _currentIndex, //當前頁面索引,高亮
         onTap: (int index){
           setState(() {
             _currentIndex = index; 
           });
         },
       ) ,
       body: blist[_currentIndex],
    );
  }
}
相關文章
相關標籤/搜索