Hướng dẫn sử dụng Flutter BottomNavigationBar

Xem thêm các chuyên mục:

1- BottomNavigationBar

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.

2- Example

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"));
  }
}

3- items

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"),
          )
        ],
      ),
    );
  }
}

4- onTap

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;
    });
  }
}

5- currentIndex

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

6- type

BottomNavigationBarType type

7- iconSize

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;
    });
  },
),

8- selectedIconTheme

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;
    });
  },
)

9- unselectedIconTheme

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;
    });
  },
),

10- selectedLabelStyle

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;
    });
  },
)

11- unselectedLabelStyle

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;
    });
  },
)

12- showSelectedLabels

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;
    });
  },
)

13- showUnselectedLabels

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;
    });
  },
)

14- selectedFontSize

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;
    });
  },
)

15- unselectedFontSize

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;
    });
  },
)

16- backgroundColor

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;
    });
  },
)

17- selectedItemColor

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;
    });
  },
)

18- unselectedItemColor

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;
    });
  },
)

19- fixedColor

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;
    });
  },
)

20- mouseCursor

MouseCursor mouseCursor
  • TODO Link!

Xem thêm các chuyên mục: