Mục lục
Hướng dẫn và ví dụ Flutter BottomNavigationBar
Xem thêm các chuyên mục:

Là một website được viết trên công nghệ web Flutter vì vậy hỗ trợ rất tốt cho người học, kể cả những người học khó tính nhất.
Hiện tại website đang tiếp tục được cập nhập nội dung cho phong phú và đầy đủ hơn. Mong các bạn nghé thăm và ủng hộ website mới của chúng tôi.


Một thanh điều hướng (navigation bar) ở dưới cùng (bottom) là một kiểu dáng truyền thống của các ứng dụng iOS. Trong Flutter, bạn có thể thực hiện được điều này với BottomNavigationBar. Ngoài ra BottomNavigationBar cũng có một tính năng tiện lợi cho phép bạn gắn thêm một FloatingActionButton vào nó
BottomNavigationBar Constructor:
BottomNavigationBar Constructor
BottomNavigationBar(
{Key key,
@required List<BottomNavigationBarItem> items,
ValueChanged<int> onTap,
int currentIndex: 0,
double elevation,
BottomNavigationBarType type,
Color fixedColor,
Color backgroundColor,
double iconSize: 24.0,
Color selectedItemColor,
Color unselectedItemColor,
IconThemeData selectedIconTheme,
IconThemeData unselectedIconTheme,
double selectedFontSize: 14.0,
double unselectedFontSize: 12.0,
TextStyle selectedLabelStyle,
TextStyle unselectedLabelStyle,
bool showSelectedLabels: true,
bool showUnselectedLabels,
MouseCursor mouseCursor}
)
BottomNavigationBar thường được đặt trong một Scaffold thông qua property AppBar.bottomNavigationBar và nó sẽ xuất hiện ở phía dưới cùng của Scaffold.

BottomNavigationBar khá giống với BottomAppBar về mục đích sử dụng. BottomNavigationBar đưa ra một khuôn mẫu để có một thanh điều hướng, vì vậy nó đơn giản và dễ dàng. Tuy nhiên, nếu bạn muốn thoả sức sáng tạo hãy sử dụng BottomAppBar.
Chúng ta sẽ bắt đầu một ví dụ hoàn chỉnh với BottomNavigationBar, nó giúp bạn hiểu được cách hoạt động của Widget này.

main.dart (ex1)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
int selectedIndex = 0;
Widget _myContacts = MyContacts();
Widget _myEmails = MyEmails();
Widget _myProfile = MyProfile();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("BottomNavigationBar Example"),
),
body: this.getBody(),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: this.selectedIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.onTapHandler(index);
},
),
);
}
Widget getBody( ) {
if(this.selectedIndex == 0) {
return this._myContacts;
} else if(this.selectedIndex==1) {
return this._myEmails;
} else {
return this._myProfile;
}
}
void onTapHandler(int index) {
this.setState(() {
this.selectedIndex = index;
});
}
}
class MyContacts extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("Contacts"));
}
}
class MyEmails extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("Emails"));
}
}
class MyProfile extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("Profile"));
}
}
Property items được sử dụng để định nghĩa danh sách các item của BottomNavigationBar. Property này là bắt buộc và số lượng item phải lớn hơn hoặc bằng 2, ngược lại bạn sẽ nhận được một lỗi.
@required List<BottomNavigationBarItem> items
BottomNavigationBarItem Constructor:
BottomNavigationBarItem Constructor
const BottomNavigationBarItem(
{@required Widget icon,
Widget title,
Widget activeIcon,
Color backgroundColor}
)
Ví dụ:

main.dart (items ex1)
import 'package:flutter/material.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: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("BottomNavigationBar Example"),
),
body: Center(
child: Text(
'Flutter BottomNavigationBar Example',
)
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text("Home"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Messages"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
),
);
}
}
onTap là một hàm callback, nó sẽ được gọi khi người dùng chạm (tap) vào một item của BottomNavigationBar.
ValueChanged<int> onTap

main.dart (onTab ex1)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
int tapCount = 0;
int selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("BottomNavigationBar Example"),
),
body: Center(
child: Text("Tap Count: " + this.tapCount.toString()
+ ", Index: " + this.selectedIndex.toString())
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: this.selectedIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.onTapHandler(index);
},
),
);
}
void onTapHandler(int index) {
this.setState(() {
this.tapCount++;
this.selectedIndex = index;
});
}
}
currentIndex là chỉ số của item đang được chọn của BottomNavigationBar, giá trị mặc định của nó là 0, tương ứng với item đầu tiên.
int currentIndex: 0
BottomNavigationBarType type
Property iconSize được sử dụng để chỉ định kích thước của biểu tượng của tất cả các BottomNavigationBarItem.
double iconSize: 24.0

iconSize (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
iconSize: 48,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
),
Property selectedIconTheme được sử dụng để thiết lập kích thước (size), mầu sắc (color) và độ mờ đục (opacity) cho biểu tượng của BottomNavigationBarItem đang được chọn.
IconThemeData selectedIconTheme
IconThemeData Constructor
const IconThemeData (
{Color color,
double opacity,
double size}
)
Nếu property selectedIconTheme được sử dụng, bạn cũng nên chỉ định giá trị cho property unselectedIconTheme, nếu không bạn sẽ không nhìn thấy các biểu tượng trên các BottomNavigationBarItem không được chọn.

selectedIconTheme (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedIconTheme: IconThemeData (
color: Colors.red,
opacity: 1.0,
size: 30
),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property unselectedIconTheme được sử dụng để thiết lập kích thước (size), mầu sắc (color) và độ mờ đục (opacity) cho biểu tượng của các BottomNavigationBarItem không được chọn.
IconThemeData unselectedIconTheme
IconThemeData constructor
const IconThemeData (
{Color color,
double opacity,
double size}
)
Nếu property unselectedIconTheme được sử dụng, bạn cũng nên chỉ định giá trị cho property selectedIconTheme, nếu không bạn sẽ không nhìn thấy biểu tượng trên BottomNavigationBarItem đang được chọn.

unselectedIconTheme (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedIconTheme: IconThemeData (
color: Colors.red,
opacity: 1.0,
size: 45
),
unselectedIconTheme: IconThemeData (
color: Colors.black45,
opacity: 0.5,
size: 25
),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
),
Property selectedLabelStyle được sử dụng để chỉ định kiểu dáng văn bản trên nhãn của BottomNavigationBarItem đang được chọn.
TextStyle selectedLabelStyle

selectedLabelStyle (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedLabelStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 22),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property unselectedLabelStyle được sử dụng để chỉ định kiểu dáng văn bản trên nhãn của các BottomNavigationBarItem không được chọn.
TextStyle unselectedLabelStyle

unselectedLabelStyle (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedLabelStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 22),
unselectedLabelStyle: TextStyle(fontStyle: FontStyle.italic),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property showSelectedLabels được sử dụng để cho phép hoặc không cho phép các nhãn (label) hiển thị trên BottomNavigationBarItem đang được chọn. Giá trị mặc định của nó là true.
bool showSelectedLabels: true

showSelectedLabels (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
showSelectedLabels: false,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property showUnselectedLabels được sử dụng để cho phép hoặc không cho phép các nhãn (label) hiển thị trên BottomNavigationBarItem không được chọn. Giá trị mặc định của nó là true.
bool showUnselectedLabels

showUnselectedLabels (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property selectedFontSize được sử dụng để chỉ định kích thước phông chữ trên BottomNavigationBarItem đang được chọn. Giá trị mặc định của nó là 14.
double selectedFontSize: 14.0

selectedFontSize (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedFontSize: 20,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property selectedFontSize được sử dụng để chỉ định kích thước phông chữ trên các BottomNavigationBarItem không được chọn. Giá trị mặc định của nó là 12.
double unselectedFontSize: 12.0

unselectedFontSize (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedFontSize: 20,
unselectedFontSize: 15,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property backgroundColor được sử dụng để chỉ định mầu nền cho BottomNavigationBar.
Color backgroundColor

backgroundColor (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
backgroundColor : Colors.greenAccent,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property selectedItemColor được sử dụng để chỉ định mầu sắc cho BottomNavigationBarItem đang được chọn, nó có tác dụng với biểu tượng và nhãn.
Chú ý: Property selectedItemColor giống với fixedColor, bạn chỉ được phép sử dụng một trong hai property này.
Color selectedItemColor

selectedItemColor (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedItemColor : Colors.red,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property unselectedItemColor được sử dụng để chỉ định mầu sắc cho các BottomNavigationBarItem không được chọn, nó có tác dụng với biểu tượng và nhãn.
Color unselectedItemColor

unselectedItemColor (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
selectedItemColor : Colors.red,
unselectedItemColor: Colors.cyan,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
Property fixedColor giống với property selectedItemColor, chúng được sử dụng để chỉ định mầu sắc cho BottomNavigationBarItem đang được chọn, nó có tác dụng với biểu tượng và nhãn.
Chú ý: fixedColor là một cái tên cũ, nó còn tồn tại vì mục đích tương thích ngược (backwards compatibility). Bạn nên sử dụng property selectedItemColor, và không được phép sử dụng đồng thời cả hai.
Color fixedColor

fixedColor (ex1)
BottomNavigationBar(
currentIndex: this.selectedIndex,
fixedColor: Colors.red,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text("Contacts"),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail),
title: Text("Emails"),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
)
],
onTap: (int index) {
this.setState(() {
this.selectedIndex = index;
});
},
)
MouseCursor mouseCursor
- TODO Link?