LoginSignup
25
23

More than 5 years have passed since last update.

FlutterでBottomNavigationBarを実装する

Last updated at Posted at 2018-06-15

BottomNavigationBar

動き

g01t6JMX1q.gif

主要な登場人物

  • Scaffold
  • PageView
  • PageController
  • BottomNavigationBar
  • BottomNavigationBarItem
  • 現在表示しているページの番号(画面用のWidgetのメンバ変数_pageとする)

実装

Scaffold

役割

表示したい画面を作成する

準備

  1. 画面用のWidgetのbuild関数の戻り値としてScaffoldを作成する(それ以外の場合もあるのかもしれない?)
class _MyHomePageState extends State<MyHomePage> {
...
  @override
  Widget build(BuildContext context) {
    // 1
    return new Scaffold(

PageController

役割

表示するページの遷移を担当する

準備

  1. 画面用のWidgetにメンバ変数として用意する
  2. 画面用のWidgetのinitState/disposeにて、作成とdisposeを呼ぶ
  3. (PageViewのcontrollerにメンバに渡す) = PageView準備:2
class _MyHomePageState extends State<MyHomePage> {
  // 1
  PageController _pageController;
  int _page = 0;

  @override
  void initState() {
    super.initState();
    // 2
    _pageController = new PageController();
  }

  @override
  void dispose() {
    super.dispose();
    // 2
    _pageController.dispose();
  }

PageView

役割

ページの見た目(BottomNavigationBarのアイコンをタップした際に切り替わるページ部分)

準備

  1. ScaffoldのbodyにPageViewを作成する
  2. PageViewのcontrollerにメンバ変数で持っているPageControllerを渡す
  3. PageViewのonPageChangedにsetStateを書いて、現在表示しているページの番号(_page)を保持する
  4. PageViewのchildrenに配列で適当なWidgetを作成する
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
...
      // 1
      body: new PageView(
        // 2
        controller: _pageController,
        // 3
        onPageChanged: onPageChanged,
        // 4
        children: [
          new HomePage(),      // StatefulWidgetを別クラスに書き出している![g01t6JMX1q.gif](https://qiita-image-store.s3.amazonaws.com/0/122320/ce1eafb4-5ba1-44c4-bfd8-f75ef99eb673.gif)

          new SettingsPage(),  // けど、Container作るとかでも大丈夫
        ],
      ),

...
  // 3(関数に分けなくても良い)
  void onPageChanged(int page) {
    setState(() {
      this._page = page;
    });
  }

BottomNavigationBar

準備

  1. ScaffoldのbottomNavigationBarにBottomNavigationBarを作成する
  2. BottomNavigationBarのitemsに配列でBottomNavigationBarItemを渡す
  3. BottomNavigationBarのonTapにPageControllerの~ToPageを実装する(当記事ではanimateToPageを使用している)
  4. BottomNavigationBarのcurrentIndexに現在表示しているページの番号(_page)を渡す

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
...
      // 1
      bottomNavigationBar: new BottomNavigationBar(
        // 4
        currentIndex: _page,
        // 3
        onTap: onTapBottomNavigation,
        // 2
        items: [
          new BottomNavigationBarItem(
              icon: new Icon(Icons.home),
              title: new Text("Home")
          ),
          new BottomNavigationBarItem(
              icon: new Icon(Icons.settings),
              title: new Text("Setting")
          ),
        ],
      ),

...
  // 3(関数に分けなくても良い)
  void onTapBottomNavigation(int page) {
    _pageController.animateToPage(
        page,
        duration: const Duration(milliseconds: 300),
        curve: Curves.ease
    );
  }

コード全文
class _MyHomePageState extends State<MyHomePage> {
  PageController _pageController;
  int _page = 0;

  @override
  void initState() {
    super.initState();
    _pageController = new PageController();
  }

  @override
  void dispose() {
    super.dispose();
    _pageController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Application Name'),
        elevation: 4.0,
      ),
      body: new PageView(
        controller: _pageController,
        onPageChanged: onPageChanged,
        children: [
          new HomePage(),
          new SettingsPage(),
        ],
      ),
      bottomNavigationBar: new BottomNavigationBar(
        currentIndex: _page,
        onTap: onTapBottomNavigation,
        items: [
          new BottomNavigationBarItem(
              icon: new Icon(Icons.home),
              title: new Text("Home")
          ),
          new BottomNavigationBarItem(
              icon: new Icon(Icons.settings),
              title: new Text("Setting")
          ),
        ],
      ),
    );
  }

  void onTapBottomNavigation(int page) {
    _pageController.animateToPage(
        page,
        duration: const Duration(milliseconds: 300),
        curve: Curves.ease
    );
  }

  void onPageChanged(int page) {
    setState(() {
      this._page = page;
    });
  }
}

参照

25
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
23