1. 程式人生 > >Flutter-1: 底部導航欄

Flutter-1: 底部導航欄

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。 通過StatefulWidgetsetState((){})方法控制它們的顯示與隱藏


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