前言
Google推出flutter這樣一個新的高性能跨平臺(Android夏跷,ios)快速開發(fā)框架之后,被業(yè)界許多開發(fā)者所關(guān)注明未。我在接觸了flutter之后發(fā)現(xiàn)這個確實是一個好東西槽华,好東西當(dāng)然要和大家分享,對吧亚隅。
今天要跟大家分享的是底部導(dǎo)航功能的實現(xiàn)硼莽。我認(rèn)為flutter的就是在傳達(dá)一種最簡設(shè)計庶溶,一個部件只關(guān)注它本身煮纵,達(dá)到低耦合高內(nèi)聚。所以本文講解底部導(dǎo)航將只關(guān)注該功能的實現(xiàn)偏螺,并對布局思路進(jìn)行介紹行疏。
你將學(xué)到什么
- 如何將部件拆分
- 如何構(gòu)建flutter布局
- 如何創(chuàng)建底部導(dǎo)航
首先讓大家看看效果。
這是一個最簡單的底部導(dǎo)航案例套像,我不希望引入過多其他東西酿联,把初學(xué)者的腦子搞得很亂(這也是我在學(xué)習(xí)中所遇到的)。
建立布局
第一步:繪制布局視圖
將布局分解為基本元素:
- 頁面是由哪些元素構(gòu)成的
- 哪些控件會因為用戶的交互而發(fā)生變化夺巩,哪些不會
在這個應(yīng)用中我們期望能夠通過點(diǎn)擊底部導(dǎo)航欄就能切換上面的整個頁面贞让。這個行為觸發(fā)了頁面的刷新。
這里我們需要思考一個問題柳譬,刷新的范圍在哪里喳张?
用過手機(jī)app的同學(xué)都知道,我們可以點(diǎn)擊底部導(dǎo)航欄美澳,底部是不會刷新的销部,而刷新的只有上面部分摸航。所以我們可以把整個頁面拆成兩部分。
第一個部分是橘色框里的頁面部分舅桩,第二個部分是我們底部的導(dǎo)航器部分酱虎。而導(dǎo)航器是一直不變的,所以導(dǎo)航器應(yīng)該是在它們之中處于父級widget層次擂涛。
第二步:開始構(gòu)造底部導(dǎo)航
class BottomNavigationWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => BottomNavigationWidgetState();
}
class BottomNavigationWidgetState extends State<BottomNavigationWidget> {
final _bottomNavigationColor = Colors.blue;
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _bottomNavigationColor,
),
title: Text(
'HOME',
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),
)),
BottomNavigationBarItem(
icon: Icon(
Icons.airplay,
color: _bottomNavigationColor,
),
title: Text(
'AIRPLAY',
style: TextStyle(color: _bottomNavigationColor),
)),
],
currentIndex: _currentIndex,
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
),
);
}
}
我們這里使用了Scaffold布局读串,它默認(rèn)提供了一個bottomNavigationBar的屬性,我們在這里給它一個BottomNavigationBar,并在這個BottomNavigationBar中放了四個BottomNavigationBarItem(一下簡稱item)歼指。每個item就是底部的一個導(dǎo)航按鈕爹土。
BottomNavigationBar的items是一個數(shù)組,那么就會存在下標(biāo)踩身。BottomNavigationBar為我們提供了一個currentIndex屬性胀茵,默認(rèn)是0,我們進(jìn)去看看這個方法。
/// The index into [items] of the current active item.
final int currentIndex;
currentIndex代表了當(dāng)前再items中被選中的index挟阻。
BottomNavigationBar還提供了一個onTap方法琼娘。我們再看看這個方法。
/// The callback that is called when a item is tapped.
/// The widget creating the bottom navigation bar needs to keep track of the
/// current index and call `setState` to rebuild it with the newly provided
/// index.
final ValueChanged<int> onTap;
當(dāng)?shù)撞繉?dǎo)航的一個item被點(diǎn)擊時附鸽,它會調(diào)用此方法脱拼,并傳入當(dāng)前item的index值,這樣就能改變焦點(diǎn)到當(dāng)前的index上的item了坷备。
我們來看看效果:
創(chuàng)建切換頁面
然后我們需要分別創(chuàng)建四個頁面熄浓,對映四個item,由于四個頁面極為相似這里只放一個省撑。建議大家對這四個頁面分別創(chuàng)建一個dart文件赌蔑。
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HOME'),
),
);
}
}
每個頁面都是一個Scaffold布局,有一個appBar竟秫。
將頁面顯示在界面上
我們再回到底部導(dǎo)航這個控件中娃惯。
由于我們是通過currentIndex這個變量來控制跳轉(zhuǎn)的,頁面要想同步也必須依賴于這個變量肥败。這里我們使用一個List<Widget>來與items對應(yīng)趾浅。
List<Widget> pages = List<Widget>();
final _bottomNavigationBarItemColor = Colors.teal;
int _currentIndex = 0;
@override
void initState() {
pages
..add(HomeScreen())
..add(EmailScreen())
..add(AlarmsScreen())
..add(ProfileScreen());
}
然后讓我們的BottomNavigation的Scaffold布局中body部分為List中的頁面。
body: pages[_bottomNavigationIndex],
我們讓_currentIndex來控制我們到底再body這個位置上顯示哪個頁面馒稍。這樣就能夠通過Tap我們的bottomNavigationItem來達(dá)到控制頁面跳轉(zhuǎn)的作用啦皿哨。
相關(guān)鏈接:
Youtube教學(xué)視頻:
https://www.youtube.com/watch?v=iYDaC2ESCkg&t=1221s
bilibili教學(xué)視頻:
https://www.bilibili.com/video/av28014369
寫在最后
如果各位還在flutter項目中遇到了底部導(dǎo)航問題,歡迎在下方評論區(qū)留言或者給我發(fā)送郵件 1652219550a@gmail.com 我會很樂意解答您的問題纽谒!