一般的なナビゲーションパターンは、画面の下部にクリック可能なアイテムを配置することです。このパターンはiOSとAndroidの両方でよく使われているので、どちらか、または両方のプラットフォームをターゲットにしている場合、このチュートリアルは重要です。これを実現するためのコンポーネントやウィジェットがBottomNavigationBarです。

このチュートリアルでは、BottomNavigationBarウィジェットとその使用方法について説明します。始めましょう。

Example 1: BottomNavigationBar - Tabs with GridViews

この例では、BottomNavigation ItemをGridViewを表示するページで切り替える方法を見ます。各ページには、異なるデータセットを持つグリッドビューが表示されます。これは、アイテムをリストアップするアプリを作成する際のテンプレートとして簡単に使用できます。

以下はそのデモです。


ビデオチュートリアル

ビデオチュートリアルをご覧ください。

Step 1: 依存関係

このプロジェクトでは特別な依存関係は必要ありません。

Step 2: BottomNavigationBarを使ったホームページの作成

まず、main.dartファイルを作成します。material`パッケージをインポートします。

import 'package:flutter/material.dart';

ステートフルなウィジェットとしてホームページを作成します。

class Homepage extends StatefulWidget {
  @override
  createState() => HomepageState();
}

ホームページの状態を作成するために、Stateを拡張します。このクラスでは、indexと呼ばれる整数のインスタンスフィールドを保持します。これは選択されたページを表します。

class HomepageState extends State<Homepage> {
  int index = 0;

appbar、body、bottomnavigationbarを含むScaffoldウィジェットを作成して返します。

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: new Text('BottomNav Grids'),
      ),
      body: HomeBody(),
      bottomNavigationBar: MyBottomNavBar(
        index: index,
        callback: (newIndex) => setState(
              () => this.index = newIndex,
            ),
      ),
    );
  }
}

Step 3: GidViewにデータを作成する

アプリの各ページには、データの入ったグリッドビューがあります。そこで、ページの表現を停止するステートレスなウィジェットが必要です。

class HomeBody extends StatelessWidget {

次に、データの入ったグリッドビューを返す関数を作ります。

 //Create and Return GridView filled with our data
  Widget createGridView(BuildContext context) {
    var spacecrafts = ["James Web","Enterprise","Hubble","Kepler","Juno","Casini","Columbia","Challenger","Mariner","Pioneer","Huygens","Galileo","Dawn","Star Dust","Apollo","Spitzer","WMAP","Swift","Atlantis"];
    spacecrafts.shuffle();
    return new GridView.builder(
      itemCount: spacecrafts.length,
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      itemBuilder: (BuildContext context, int index) {
        return new GestureDetector(
          child: new Card(
            elevation: 5.0,
            child: new Container(
              alignment: Alignment.centerLeft,
              margin: new EdgeInsets.only(top: 10.0, bottom: 10.0,left: 10.0),
              child: new Text(spacecrafts[index]),
            ),
          ),
    );
    }
    );
  }

次に、グリッドビューを中心にページを表現するウィジェットを作ります。

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: createGridView(context),
      ),
    );
  }
}

Step 4: ボトムナビゲーションバーの作成

bottomnavigationbarは、他のウィジェットと同様に、それ自体がウィジェットです。そのため、プログラムで作成する必要があります。ここでは、StatelessWidgetを拡張し、build()メソッドをオーバーライドして作成します。

class MyBottomNavBar extends StatelessWidget {

2つのインスタンスフィールドを定義します。これらのフィールドには、コンストラクタで受け取る引数が格納されます。

  MyBottomNavBar({this.index, this.callback});

  final int index;
  final Function(int) callback;

ここでは、テキストとアイコンを含む3つのアイテムを持つボトムナビゲーションバーを構築し、返す方法を説明します。

  @override
  Widget build(BuildContext context) {
    /// BottomNavigationBar is automatically set to type 'fixed'
    /// when there are three of less items
    return BottomNavigationBar(
      currentIndex: index,
      onTap: callback,
      items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          title: Text('Plasma'),
        ),
         BottomNavigationBarItem(
          icon: Icon(Icons.usb),
          title: Text('Laser'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.threed_rotation),
          title: Text('Warp'),
        ),
      ],
    );
  }
}

フルコード

以下にフルコードを示します。

main.dart

import 'package:flutter/material.dart';

class Homepage extends StatefulWidget {
  @override
  createState() => HomepageState();
}

class HomepageState extends State<Homepage> {
  int index = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: new Text('BottomNav Grids'),
      ),
      body: HomeBody(),
      bottomNavigationBar: MyBottomNavBar(
        index: index,
        callback: (newIndex) => setState(
              () => this.index = newIndex,
            ),
      ),
    );
  }
}

//This represents the Body. We show GridView in Body
class HomeBody extends StatelessWidget {

  //Create and Return GridView filled with our data
  Widget createGridView(BuildContext context) {
    var spacecrafts = ["James Web","Enterprise","Hubble","Kepler","Juno","Casini","Columbia","Challenger","Mariner","Pioneer","Huygens","Galileo","Dawn","Star Dust","Apollo","Spitzer","WMAP","Swift","Atlantis"];
    spacecrafts.shuffle();
    return new GridView.builder(
      itemCount: spacecrafts.length,
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      itemBuilder: (BuildContext context, int index) {
        return new GestureDetector(
          child: new Card(
            elevation: 5.0,
            child: new Container(
              alignment: Alignment.centerLeft,
              margin: new EdgeInsets.only(top: 10.0, bottom: 10.0,left: 10.0),
              child: new Text(spacecrafts[index]),
            ),
          ),
    );
    }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: createGridView(context),
      ),
    );
  }
}

class MyBottomNavBar extends StatelessWidget {
  MyBottomNavBar({this.index, this.callback});

  final int index;
  final Function(int) callback;

  @override
  Widget build(BuildContext context) {
    /// BottomNavigationBar is automatically set to type 'fixed'
    /// when there are three of less items
    return BottomNavigationBar(
      currentIndex: index,
      onTap: callback,
      items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          title: Text('Plasma'),
        ),
         BottomNavigationBarItem(
          icon: Icon(Icons.usb),
          title: Text('Laser'),
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.threed_rotation),
          title: Text('Warp'),
        ),
      ],
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Bottom Navigation',
        theme: ThemeData(
          primarySwatch: Colors.deepOrange,
        ),
        home: Homepage());
  }
}

void main() => runApp(MyApp());
ダウンロード

参考資料はこちらです。

Number Location Link
1. GitHub Direct Download
2. GitHub Browse
3. YouTube Video Tutorial
4. YouTube ProgrammingWizards TV Channel

Categorized in: