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()方法:

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

這里的..add()是Dart語言的..語法,如果你學過編程模式,你一定聽說過建造者模式,簡單來說就是返回調用者本身。這里list后用了..add(),還會返回list,然后就一直使用..語法,能一直想list里增加widget元素。 最后我們調用了一些父類的initState()方法。

完整代碼:

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],
    );
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM