您好,登錄后才能下訂單哦!
本篇文章為大家展示了使用Flutter怎么實(shí)現(xiàn)一個(gè)底部菜單導(dǎo)航,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
程序工程目錄
梳理下實(shí)現(xiàn)步驟
我們需要實(shí)現(xiàn)這個(gè)底部菜單導(dǎo)航,就需要有底部菜單的那一排圖標(biāo)按鈕。圖標(biāo)按鈕是固定在一個(gè)工具欄 “bar” 上面。然后呢,需要分別需要有按鈕對(duì)應(yīng)的界面,就是說按鈕有多少個(gè),那么界面需要對(duì)應(yīng)的有多少個(gè)。我們來一個(gè)清單列表:
按鈕圖標(biāo)區(qū)域。由于展示的方式都是一樣的,我們需要有一個(gè)單獨(dú)的控件,循環(huán)出來就好。
工具欄區(qū)域。用于展示按鈕圖標(biāo),并且能固定在底部。
首頁。用于將工具欄放入界面中,并且將按鈕對(duì)應(yīng)的界面作為它的子元素存放于其中。
不同的按鈕對(duì)應(yīng)的界面。在我們點(diǎn)擊的圖標(biāo)按鈕的時(shí)候,展示不同的界面。
我們底部的按鈕是不會(huì)刷新的,界面會(huì)刷新,如何實(shí)現(xiàn)?
我們界面展示區(qū)域分為兩塊,一塊展示底部的工具欄,一塊展示頁面。下面代碼實(shí)現(xiàn):
return new MaterialApp( home: new Scaffold( body: new Center( child: _currentPage // 動(dòng)態(tài)的展示我們當(dāng)前的頁面 ), bottomNavigationBar: bottomNavigationBar, // 底部工具欄 ), theme: new ThemeData( primarySwatch: Colors.blue, // 設(shè)置主題顏色 ), );
具體實(shí)現(xiàn)
第一步:創(chuàng)建一個(gè) flutter 工程
可以按照工程目錄圖中的結(jié)構(gòu),將對(duì)應(yīng)的文件建好。
第二步:修改 main.dart。
main.dart 是我們程序的入口。就類似于 Java、C 中的 main() ,作為一個(gè)程序的入口。我們將 main.dart 作為程序的啟動(dòng)入口,就不做過多的操作,只是指定去加載我們的首頁(index.dart)。
main.dart
import 'package:flutter/material.dart'; import 'package:flutter_demo/index/index.dart'; // 導(dǎo)入index.dart // 這里為入口函數(shù) void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', home: new Index(), // 指定去加載 Index頁面。 ); } }
第三步:創(chuàng)建 NavigationIconView。
正如前面說的,我們底部的按鈕區(qū)域展示的圖標(biāo)加上文字是固定格式,所以將這一部分抽取出來,作為一個(gè)公共的 class,方便界面程序維護(hù)。
navigation_icon_view.dart
import 'package:flutter/material.dart'; // 創(chuàng)建一個(gè) Icon 展示控件 class NavigationIconView { // 創(chuàng)建兩個(gè)屬性,一個(gè)是 用來展示 icon, 一個(gè)是動(dòng)畫處理 final BottomNavigationBarItem item; final AnimationController controller; // 類似于 java 中的構(gòu)造方法 // 創(chuàng)建 NavigationIconView 需要傳入三個(gè)參數(shù), icon 圖標(biāo),title 標(biāo)題, TickerProvider NavigationIconView({Widget icon, Widget title, TickerProvider vsync}): item = new BottomNavigationBarItem( icon: icon, title: title, ), controller = new AnimationController( duration: kThemeAnimationDuration, // 設(shè)置動(dòng)畫持續(xù)的時(shí)間 vsync: vsync // 默認(rèn)屬性和參數(shù) ); }
第四步:創(chuàng)建 Index
這一步就比較重要了,因?yàn)槲覀冃枰谶@個(gè)界面上面去布局,以及實(shí)現(xiàn)點(diǎn)擊按鈕圖標(biāo)之后,有事件觸發(fā)。正因?yàn)槲覀冃枰惺录|發(fā),所以創(chuàng)建一個(gè)帶有狀態(tài)的 Widget(StatefulWidget)。下面的代碼注釋給的很詳細(xì)了,可以仔細(xì)看。
index.dart
import 'package:flutter/material.dart'; import 'package:flutter_demo/NoticePage/notice_page.dart'; import 'package:flutter_demo/home/home_page.dart'; import 'package:flutter_demo/idea/idea_page.dart'; import 'package:flutter_demo/market/market_page.dart'; import 'package:flutter_demo/my/my_page.dart'; import 'navigation_icon_view.dart'; // 如果是在同一個(gè)包的路徑下,可以直接使用對(duì)應(yīng)的文件名 // 創(chuàng)建一個(gè) 帶有狀態(tài)的 Widget Index class Index extends StatefulWidget { // 固定的寫法 @override State<StatefulWidget> createState() => new _IndexState(); } // 要讓主頁面 Index 支持動(dòng)效,要在它的定義中附加mixin類型的對(duì)象TickerProviderStateMixin class _IndexState extends State<Index> with TickerProviderStateMixin{ int _currentIndex = 0; // 當(dāng)前界面的索引值 List<NavigationIconView> _navigationViews; // 底部圖標(biāo)按鈕區(qū)域 List<StatefulWidget> _pageList; // 用來存放我們的圖標(biāo)對(duì)應(yīng)的頁面 StatefulWidget _currentPage; // 當(dāng)前的顯示頁面 // 定義一個(gè)空的設(shè)置狀態(tài)值的方法 void _rebuild() { setState((){}); } @override void initState() { super.initState(); // 初始化導(dǎo)航圖標(biāo) _navigationViews = <NavigationIconView>[ new NavigationIconView(icon: new Icon(Icons.assessment), title: new Text("首頁"), vsync: this), // vsync 默認(rèn)屬性和參數(shù) new NavigationIconView(icon: new Icon(Icons.all_inclusive), title: new Text("想法"), vsync: this), new NavigationIconView(icon: new Icon(Icons.add_shopping_cart), title: new Text("市場(chǎng)"), vsync: this), new NavigationIconView(icon: new Icon(Icons.add_alert), title: new Text("通知"), vsync: this), new NavigationIconView(icon: new Icon(Icons.perm_identity), title: new Text("我的"), vsync: this), ]; // 給每一個(gè)按鈕區(qū)域加上監(jiān)聽 for (NavigationIconView view in _navigationViews) { view.controller.addListener(_rebuild); } // 將我們 bottomBar 上面的按鈕圖標(biāo)對(duì)應(yīng)的頁面存放起來,方便我們?cè)邳c(diǎn)擊的時(shí)候 _pageList = <StatefulWidget>[ new HomePage(), new IdeaPage(), new MarketPage(), new NoticePage(), new MyPage() ]; _currentPage = _pageList[_currentIndex]; } @override Widget build(BuildContext context) { // 聲明定義一個(gè) 底部導(dǎo)航的工具欄 final BottomNavigationBar bottomNavigationBar = new BottomNavigationBar( items: _navigationViews .map((NavigationIconView navigationIconView) => navigationIconView.item) .toList(), // 添加 icon 按鈕 currentIndex: _currentIndex, // 當(dāng)前點(diǎn)擊的索引值 type: BottomNavigationBarType.fixed, // 設(shè)置底部導(dǎo)航工具欄的類型:fixed 固定 onTap: (int index){ // 添加點(diǎn)擊事件 setState((){ // 點(diǎn)擊之后,需要觸發(fā)的邏輯事件 _navigationViews[_currentIndex].controller.reverse(); _currentIndex = index; _navigationViews[_currentIndex].controller.forward(); _currentPage = _pageList[_currentIndex]; }); }, ); return new MaterialApp( home: new Scaffold( body: new Center( child: _currentPage // 動(dòng)態(tài)的展示我們當(dāng)前的頁面 ), bottomNavigationBar: bottomNavigationBar, // 底部工具欄 ), theme: new ThemeData( primarySwatch: Colors.blue, // 設(shè)置主題顏色 ), ); } }
第四步:創(chuàng)建頁面
前面的步驟都是在搭建我們的基礎(chǔ),現(xiàn)在是做展示界面。由于不同的界面,對(duì)應(yīng)的源碼都是和下面的是一樣的,只是 class 的名字不一樣,就都可以使用同樣的模版復(fù)制過去就有可以了。
home_page.dart
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, ), ), ); } }
idea_page.dart
import 'package:flutter/material.dart'; class IdeaPage extends StatefulWidget{ @override State<StatefulWidget> createState() => new _IdeaPageState(); } class _IdeaPageState extends State<IdeaPage> { @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, ), ), ); } }
market_page.dart
import 'package:flutter/material.dart'; class MarketPage extends StatefulWidget{ @override State<StatefulWidget> createState() => new _MarketPageState(); } class _MarketPageState extends State<MarketPage> { @override Widget build(BuildContext context) { return new MaterialApp( home: new Scaffold( appBar: new AppBar( title: new Text('市場(chǎng)'), // 后面的省略 // ...... ) ), ); } }
上述內(nèi)容就是使用Flutter怎么實(shí)現(xiàn)一個(gè)底部菜單導(dǎo)航,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。