Flutter-1: 底部導航欄
阿新 • • 發佈:2018-12-14
Flutter - 1 : 底部導航欄
預覽圖,大概就是這個熊樣的,對,顏值是襯托來的,其實還是。。。要什麼自行車。。。
-
1.ymal新增支援包
EventBus的flutter版。
event_bus: ">=1.0.0<2.0.0"
-
2.建立App
一個簡單的,沒啥玩意的,連主題都只有一行的application。
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'FlutterApplication',
theme: new ThemeData(
primaryColor: Colors.blue,
),
home: new MainPage());
}
}
-
3.主頁面
該加的還是加一下,Title左邊和右邊的按鈕,雖然並沒有什麼卵用。然後把body頁面和導航用的Item給建立好,寫在一塊方便改;
// 主頁面
class MainPage extends StatelessWidget {
final String appbar_title = "ForFun";
final List<Widget> body_pages = new List<Widget>();
final List<BottomNavigationBarItem> bottom_items = new List<BottomNavigationBarItem>();
@override
Widget build(BuildContext context) {
setBodyViews();
setBottomItems ();
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(
icon: new Icon(Icons.format_list_bulleted),
onPressed: () {
print("Left Icon Printed");
}),
title: new Text(
appbar_title,
style: new TextStyle(fontWeight: FontWeight.bold),
),
centerTitle: true,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.more_vert),
onPressed: () {
print("Right Icon Printed");
})
],
),
body: new BodyPage(
body_pages: body_pages,
),
bottomNavigationBar: new BottomNavigator(
bottom_items: bottom_items,
),
);
}
// body頁面
void setBodyViews() {
body_pages
..add(new BodyPageA())
..add(new BodyPageB())
..add(new BodyPageC());
}
// bottom導航
void setBottomItems() {
TextStyle _navigate_bar_style =
new TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold);
bottom_items
..add(new BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text(
"Home",
style: _navigate_bar_style,
)))
..add(new BottomNavigationBarItem(
icon: new Icon(Icons.photo_album),
title: new Text(
"Photos",
style: _navigate_bar_style,
)))
..add(new BottomNavigationBarItem(
icon: new Icon(Icons.video_library),
title: new Text(
"Videos",
style: _navigate_bar_style,
)));
}
}
-
4.頁面主體
把上面new
出來的頁面放進Stack
,然後再在外面包一層Offstage
。
通過StatefulWidget
的setState((){})
方法控制它們的顯示與隱藏
// Body部分的頁面
class BodyPage extends StatefulWidget {
final List<Widget> body_pages;
BodyPage({Key key, this.body_pages}) : super(key: key);
@override
State<StatefulWidget> createState() {
return new _BodyPageState(body_pages);
}
}
class _BodyPageState extends State<BodyPage> {
final List<Widget> body_pages;
List<Offstage> _body = new List<Offstage>();
int _len = 0;
int _current_position = 0;
_BodyPageState(this.body_pages);
@override
void initState() {
super.initState();
_len = body_pages.length;
createBodyPage();
onSelectChanged();
}
@override
Widget build(BuildContext context) {
return Stack(
children: _body,
);
}
void createBodyPage(){
_body.clear();
for(int i=0;i<_len;i++){
if(i == _current_position){
_body.add(new Offstage(offstage: false,child: body_pages[i],));
}else{
_body.add(new Offstage(offstage: true,child: body_pages[i],));
}
}
}
void onSelectChanged() {
Event.event_bus.on<MainSelectedTab>().listen((MainSelectedTab events) {
int position = events.message;
if (_current_position != position) {
setState(() {
_current_position = position;
createBodyPage();
});
}
});
}
}
-
5.底部導航欄
跟body頁面同樣的待遇,只是不需要隱藏了,點選之後呼叫setState((){})
重新整理控制元件,然後通過EventBus發訊息通知dody部分隱藏和顯示頁面就好了。
// Bottom部分的導航欄
class BottomNavigator extends StatefulWidget {
final List<BottomNavigationBarItem> bottom_items;
BottomNavigator({Key key, this.bottom_items}) : super(key: key);
@override
State<StatefulWidget> createState() {
return new _BottomNavigatorState(bottom_items);
}
}
class _BottomNavigatorState extends State<BottomNavigator> {
final List<BottomNavigationBarItem> bottom_items;
int _current_position = 0;
_BottomNavigatorState(this.bottom_items);
@override
Widget build(BuildContext context) {
return new BottomNavigationBar(
currentIndex: _current_position,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.blue,
items: bottom_items,
onTap: (int position) {
setState(() {
_current_position = position;
Event.event_bus.fire(new MainSelectedTab(position));
});
},
);
}
}
-
6.底部導航欄EventBus通訊類
最後把EventBus監聽的訊息類加上。
class MainSelectedTab{
final int message;
MainSelectedTab(this.message);
}