Flutter——底部導航

1,建立單個導航圖標文字組件文件

import 'package:flutter/material.dart';

class NavigationIconView {
  // 建立兩個屬性,一個是 用來展現 icon, 一個是動畫處理
  final BottomNavigationBarItem item;
  final AnimationController controller;

  // 相似於 java 中的構造方法
  // 建立 NavigationIconView 須要傳入三個參數, icon 圖標,title 標題, TickerProvider
  NavigationIconView({Widget icon, Widget title, TickerProvider vsync})
      : item = new BottomNavigationBarItem(
    icon: icon,
    title: title,
  ),
        controller = new AnimationController(
            duration: kThemeAnimationDuration, // 設置動畫持續的時間
            vsync: vsync // 默認屬性和參數
        );
}複製代碼

2,建立4個頁面home,course,book,my,如下只列出其中一個頁面代碼,其餘都同樣

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('首頁'),
          actions: <Widget>[
            new Container()
          ],
        ),
        body: new Center(
          child: null,
        ),
      ),
    );
  }
}
複製代碼

3,建立index頁面,用來渲染導航的佈局

import 'package:flutter/material.dart';
import 'package:flutter_app/home/home_page.dart';
import 'package:flutter_app/course/course_page.dart';
import 'package:flutter_app/book/book_page.dart';
import 'package:flutter_app/my/my_page.dart';

import 'package:flutter_app/navigation_icon_view.dart'; // 若是是在同一個包的路徑下,能夠直接使用對應的文件名

// 建立一個 帶有狀態的 Widget Index
class Index extends StatefulWidget {
  //  固定的寫法
  @override
  State<StatefulWidget> createState() => new _IndexState();
}

// 要讓主頁面 Index 支持動效,要在它的定義中附加mixin類型的對象TickerProviderStateMixin
class _IndexState extends State<Index> with TickerProviderStateMixin {
  int _currentIndex = 0; // 當前界面的索引值
  List<NavigationIconView> _navigationViews; // 底部圖標按鈕區域
  List<StatefulWidget> _pageList; // 用來存放咱們的圖標對應的頁面
  StatefulWidget _currentPage; // 當前的顯示頁面

  // 定義一個空的設置狀態值的方法
  void _rebuild() {
    setState(() {});
  }

  @override
  void initState() {
    super.initState();

    // 初始化導航圖標
    _navigationViews = <NavigationIconView>[
      new NavigationIconView(
          icon: new Icon(Icons.home), title: new Text("首頁"), vsync: this),
      // vsync 默認屬性和參數
      new NavigationIconView(
          icon: new Icon(Icons.videocam),
          title: new Text("課程"),
          vsync: this),
      new NavigationIconView(
          icon: new Icon(Icons.book), title: new Text("書籍"), vsync: this),
      new NavigationIconView(
          icon: new Icon(Icons.perm_identity),
          title: new Text("個人"),
          vsync: this),
    ];

    // 給每個按鈕區域加上監聽
    for (NavigationIconView view in _navigationViews) {
      view.controller.addListener(_rebuild);
    }

    // 將咱們 bottomBar 上面的按鈕圖標對應的頁面存放起來,方便咱們在點擊的時候
    _pageList = <StatefulWidget>[
       HomePage(),
       CoursePage(),
       BookPage(),
       MyPage()
    ];
    _currentPage = _pageList[_currentIndex];
  }

  @override
  Widget build(BuildContext context) {
    // 聲明定義一個 底部導航的工具欄
    final BottomNavigationBar bottomNavigationBar = new BottomNavigationBar(
      items: _navigationViews
          .map((NavigationIconView navigationIconView) =>
              navigationIconView.item)
          .toList(), // 添加 icon 按鈕
      currentIndex: _currentIndex, // 當前點擊的索引值
      type: BottomNavigationBarType.fixed, // 設置底部導航工具欄的類型:fixed 固定
      onTap: (int index) {
        // 添加點擊事件
        setState(() {
          // 點擊以後,須要觸發的邏輯事件
          _navigationViews[_currentIndex].controller.reverse();
          _currentIndex = index;
          _navigationViews[_currentIndex].controller.forward();
          _currentPage = _pageList[_currentIndex];
        });
      },
    );

    return new MaterialApp(
      home: new Scaffold(
        body: new Center(child: _currentPage // 動態的展現咱們當前的頁面
            ),
        bottomNavigationBar: bottomNavigationBar, // 底部工具欄
      ),
      theme: new ThemeData(
        primarySwatch: Colors.blue, // 設置主題顏色
      ),
    );
  }
}


複製代碼

4,main.dart代碼以下

import 'package:flutter/material.dart';
import 'package:flutter_app/index/Index.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primaryColor: Colors.red,
      ),
      home: Index(),
    );
  }
}



複製代碼

5,測試運行

相關文章
相關標籤/搜索