# Navigation router
## ButtomTabs 底部的切換頁

會使用到的內建widget:
1. BottomNavigationBar
2. BottomNavigationBarItem
#### main.dart
```java
import 'src/widgets/ButtomTabs.dart';
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: GlobalLayout(title: 'flutter_router_demo'),
);
}
}
void main() => runApp(App());
```
```java
class GlobalLayout extends StatefulWidget {
@override
GlobalLayoutState createState() => GlobalLayoutState();
}
class GlobalLayoutState extends State<GlobalLayout> {
int current = 0;
void onChangeTab(int n) {
setState(() {
current = n;
});
}
return Scaffold(
//...
bottomNavigationBar: ButtomTabs(
current: current,
onChangeTab: onChangeTab,
)
)
}
```
#### ButtomTabs.dart
```java
import 'package:flutter/material.dart';
class ButtomTabs extends StatelessWidget {
ButtomTabs({this.current, this.onChangeTab});
final int current;
final Function onChangeTab;
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed, //超過3個item要強制設定fixed
currentIndex: current,
items: [
BottomNavigationBarItem(title: Text("Home"), icon: Icon(Icons.home)),
BottomNavigationBarItem(title: Text("List"), icon: Icon(Icons.list)),
BottomNavigationBarItem(
title: Text("Message"), icon: Icon(Icons.message)),
],
onTap: onChangeTab);
}
}
```
當`BottomNavigationBarItem`數量超過3個的時候,`BottomNavigationBar`的`type`會從預設的`fixed`變成`shifting`,所以假設要放到4個或5個,要手動指定`type:BottomNavigationBarType.fixed`。
---
## Drawer 左邊打開的漢堡選單
 
#### main.dart
```java
return Scaffold(
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.red,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
),
ListTile(leading: Icon(Icons.access_alarms), title: Text('Alert')),
ListTile(leading: Icon(Icons.device_hub), title: Text('Device')),
],
))
)
```
### 使用`Listview.build()`
#### main.dart
```java
return Scaffold(
drawer: DrawerItems(),
)
```
#### DrawerItems.dart
```java
import 'package:flutter/material.dart';
class DrawerItems extends StatelessWidget {
final List<Map<String, dynamic>> menus = [
{'name': 'Home', 'icon': 59530},
{'name': 'Account', 'icon': 59705},
{'name': 'Setting', 'icon': 59576},
];
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: menus.length + 1,
itemBuilder: (BuildContext context, int i) {
if (i == 0) {
return DrawerHeader(
decoration: BoxDecoration(
color: Colors.red,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
);
}
return ListTile(
leading: Icon(IconData(menus[i - 1]["icon"],
fontFamily: 'MaterialIcons')),
title: Text(menus[i - 1]["name"]),
);
}));
}
}
```
- `Drawer`:會從左邊打開一個固定寬度的區域,如果不加上這個,左側選單會變成滿版的。
- `itemCount`:因為最上面要新增一個`DrawerHeader`,所以`itemCount`要+1。
- `return`:`(i == 0)`的時候return `DrawerHeader`,其他時候return 一般的`ListTile`。
### 加入點擊事件
#### main.dart
加入`router`
```java
import 'src/pages/PageWrap.dart';
return MaterialApp(
routes: <String, WidgetBuilder>{
'/account': (BuildContext context) => PageWrap(title: 'Account'),
'/setting': (BuildContext context) => PageWrap(title: 'Setting'),
},
)
```
#### DrawerItems.dart
- 選單的資料中,加入`path`資料。
```java
final List<Map<String, dynamic>> menus = [
{'name': 'Home', 'icon': 59530},
{'name': 'Account', 'path': 'account', 'icon': 59705},
{'name': 'Setting', 'path': 'setting', 'icon': 59576},
];
```
- `pushNamed`裡面是要放`/path/name`這種資料,所以字串前面加上一個`/`
```java
return ListTile(
//...
onTap: () {
Navigator.of(context).pushNamed('/${menus[i - 1]["path"]}');
},
);
```
#### PageWrap.dart
```java
import 'package:flutter/material.dart';
class PageWrap extends StatelessWidget {
PageWrap({this.title});
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(title),
),
);
}
}
```