最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter實現(xiàn)底部菜單導(dǎo)航

 更新時間:2022年03月23日 08:36:59   作者:Wayfreem  
這篇文章主要為大家詳細(xì)介紹了Flutter實現(xiàn)底部菜單導(dǎo)航,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

簡介

現(xiàn)在我們的 APP 上面都會在屏幕下方有一排的按鈕,點擊不同的按鈕可以進(jìn)入不同的界面。就是說在界面的底部會有一排的按鈕導(dǎo)航??煽聪旅娴膱D示。

完成圖示

程序工程目錄

程序工程目錄

梳理下實現(xiàn)步驟

我們需要實現(xiàn)這個底部菜單導(dǎo)航,就需要有底部菜單的那一排圖標(biāo)按鈕。圖標(biāo)按鈕是固定在一個工具欄 “bar” 上面。然后呢,需要分別需要有按鈕對應(yīng)的界面,就是說按鈕有多少個,那么界面需要對應(yīng)的有多少個。我們來一個清單列表:

  • 按鈕圖標(biāo)區(qū)域。由于展示的方式都是一樣的,我們需要有一個單獨的控件,循環(huán)出來就好。
  • 工具欄區(qū)域。用于展示按鈕圖標(biāo),并且能固定在底部。
  • 首頁。用于將工具欄放入界面中,并且將按鈕對應(yīng)的界面作為它的子元素存放于其中。
  • 不同的按鈕對應(yīng)的界面。在我們點擊的圖標(biāo)按鈕的時候,展示不同的界面。

我們底部的按鈕是不會刷新的,界面會刷新,如何實現(xiàn)?

我們界面展示區(qū)域分為兩塊,一塊展示底部的工具欄,一塊展示頁面。下面代碼實現(xiàn):

return new MaterialApp(
  home: new Scaffold(
   body: new Center(
    child: _currentPage // 動態(tài)的展示我們當(dāng)前的頁面
   ),
   bottomNavigationBar: bottomNavigationBar, // 底部工具欄
  ),

  theme: new ThemeData(
  primarySwatch: Colors.blue, // 設(shè)置主題顏色
  ),

 );

具體實現(xiàn)

第一步:創(chuàng)建一個 flutter 工程
可以按照工程目錄圖中的結(jié)構(gòu),將對應(yīng)的文件建好。

第二步:修改 main.dart。
main.dart 是我們程序的入口。就類似于 Java、C 中的 main() ,作為一個程序的入口。我們將 main.dart 作為程序的啟動入口,就不做過多的操作,只是指定去加載我們的首頁(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)加上文字是固定格式,所以將這一部分抽取出來,作為一個公共的 class,方便界面程序維護(hù)。

navigation_icon_view.dart

import 'package:flutter/material.dart';

// 創(chuàng)建一個 Icon 展示控件
class NavigationIconView {

 // 創(chuàng)建兩個屬性,一個是 用來展示 icon, 一個是動畫處理
 final BottomNavigationBarItem item;
 final AnimationController controller;

 // 類似于 java 中的構(gòu)造方法
 // 創(chuàng)建 NavigationIconView 需要傳入三個參數(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è)置動畫持續(xù)的時間
  vsync: vsync       // 默認(rèn)屬性和參數(shù)
 );
}

第四步:創(chuàng)建 Index

這一步就比較重要了,因為我們需要在這個界面上面去布局,以及實現(xiàn)點擊按鈕圖標(biāo)之后,有事件觸發(fā)。正因為我們需要有事件觸發(fā),所以創(chuàng)建一個帶有狀態(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'; // 如果是在同一個包的路徑下,可以直接使用對應(yīng)的文件名

// 創(chuàng)建一個 帶有狀態(tài)的 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; // 當(dāng)前界面的索引值
 List<NavigationIconView> _navigationViews; // 底部圖標(biāo)按鈕區(qū)域
 List<StatefulWidget> _pageList; // 用來存放我們的圖標(biāo)對應(yīng)的頁面
 StatefulWidget _currentPage; // 當(dāng)前的顯示頁面

 // 定義一個空的設(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("市場"), 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),
 ];

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

 // 將我們 bottomBar 上面的按鈕圖標(biāo)對應(yīng)的頁面存放起來,方便我們在點擊的時候
 _pageList = <StatefulWidget>[
  new HomePage(),
  new IdeaPage(),
  new MarketPage(),
  new NoticePage(),
  new MyPage()
 ];
 _currentPage = _pageList[_currentIndex];
 }

 @override
 Widget build(BuildContext context) {

 // 聲明定義一個 底部導(dǎo)航的工具欄
 final BottomNavigationBar bottomNavigationBar = new BottomNavigationBar(
  items: _navigationViews
   .map((NavigationIconView navigationIconView) => navigationIconView.item)
   .toList(), // 添加 icon 按鈕
  currentIndex: _currentIndex, // 當(dāng)前點擊的索引值
  type: BottomNavigationBarType.fixed, // 設(shè)置底部導(dǎo)航工具欄的類型:fixed 固定
  onTap: (int index){ // 添加點擊事件
  setState((){ // 點擊之后,需要觸發(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 // 動態(tài)的展示我們當(dāng)前的頁面
   ),
   bottomNavigationBar: bottomNavigationBar, // 底部工具欄
  ),

  theme: new ThemeData(
  primarySwatch: Colors.blue, // 設(shè)置主題顏色
  ),

 );
 }

}

第四步:創(chuàng)建頁面

前面的步驟都是在搭建我們的基礎(chǔ),現(xiàn)在是做展示界面。由于不同的界面,對應(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('市場'),
   // 后面的省略
   // ......
  )
  ),
 );
 }

}

剩下的界面都是一樣子的了,就不貼出來了,都是復(fù)制一下,改了一個類名,和顯示的文字而已。

第五步:啟動測試

到此我們就完成了,可以啟動程序,看下效果。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

长宁区| 中牟县| 夏津县| 阿瓦提县| 东乌珠穆沁旗| 乌苏市| 金沙县| 牡丹江市| 翁牛特旗| 汤原县| 兴仁县| 尉犁县| 盐城市| 勐海县| 三明市| 安康市| 兴宁市| 桃园市| 韩城市| 阳信县| 大理市| 拉孜县| 南和县| 崇阳县| 繁昌县| 高青县| 泰和县| 象山县| 稷山县| 界首市| 额济纳旗| 绥江县| 巫山县| 镇平县| 茂名市| 灵宝市| 锡林浩特市| 馆陶县| 涪陵区| 屏边| 嘉祥县|