【Flutter】bottom_Navy_barを用いたタブバー作成と、それに合わせたページ遷移を実装してみました。

筆者

・Flutterでタブバーの作り方わからない。。
・タブバーは表示されたんだけど対応ページをどうやって表示させるんだろう。。
・タブバーのおすすめのパッケージと使い方を知りたい。。

本記事では、そんなタブバーで悩んでいる方向けに記事をまとめています。

目次

今回使用するタブバー

今回は、下図のようなTabbarをパッケージをインストールして使用します。

パッケージのインポート

プロジェクトに下記URLのパッケージをインポートしてください。

Dart packages
bottom_navy_bar | Flutter package A beautiful and animated bottom navigation. The navigation bar use your current theme, but you are free to customize it.

パッケージのインストール方法などがわからない方は、下記記事を参考にしてください。

https://flutternyumon.com/flutter-how-to-install-package/

そもそもプロジェクトの立ち上げ方などからわからない。。という方は、こちらの記事から読み進めてください。

あわせて読みたい
【Flutter】アプリ開発チュートリアル(1日目) こんにちは。独学でプログラミングを行なっています。 今回集中的にFlutterを学んでアプリを作るぞ!と一念発起したのでその経過を描くことにしました。 本記事では、ア...

各ページのファイルを作成する。

今回は、5画面(タブバーのみだと4画面ですが、floating button用にもう1画面作っています)作成するため、それぞれのdartファイルを作成します。下のようにdartファイルが作れたらokです。

新規dartファイルの作成方法は下記を確認ください。

あわせて読みたい
【Flutter】アプリ開発チュートリアル(1日目) こんにちは。独学でプログラミングを行なっています。 今回集中的にFlutterを学んでアプリを作るぞ!と一念発起したのでその経過を描くことにしました。 本記事では、ア...

各ファイルにデフォルトの文を記載する

main.dartを除く各ページのdartファイルには、下記の様に記載します。

import 'package:flutter/material.dart';

class History extends StatefulWidget {
  @override
  _HistoryState createState() => _HistoryState();
}

class _HistoryState extends State<History> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Text("History")
      ),
    );
  }
}

これらのコードはmain.dartでも記載されている文です。ファイル名に合わせてclass名を変更しておきます。

main.dartの文章をパッケージの例文に置き換える

下記に、パッケージを使ったコードの例が記載されています。main.dartの文章を書き換えましょう。

最初のimport部分は、各ファイル名.dartの文が残るようにしてください。

Dart packages
bottom_navy_bar example | Flutter package A beautiful and animated bottom navigation. The navigation bar use your current theme, but you are free to customize it.

PageControllerの呼び出し

PageControllerは、PageViewの中でどのページを見せるか操作するクラスです。

あわせて読みたい
PageController class - widgets library - Dart API API docs for the PageController class from the widgets library, for the Dart programming language.

下記のように、pagecontrollerを宣言します。

class _MyHomePageState extends State<MyHomePage> {
  PageController _pageController = PageController(initialPage: 0);

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

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

次に、viewListを作ります。

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }
  int _currentIndex = 0;
  int _counter = 0;

//以下を追記
  List<Widget> viewList = [
      Home(),  
      Graph(),
      History(),
      Setting()
     
    ];
//ここまで

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

これで、各画面の行列ができました。

最後に、bodyを作成した行列にすれば完了です。

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Flutter Demo")),
      body: viewList[_currentIndex],

コード全文

記事最初にあった画面のコードの全文を記載しておきます。

import 'package:bottom_navy_bar/bottom_navy_bar.dart';
import 'package:flutter/material.dart';
import 'package:stylerecord/graph.dart';
import 'package:stylerecord/history.dart';
import 'package:stylerecord/home.dart';
import 'package:stylerecord/setting.dart';
import 'package:stylerecord/record.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget{

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  PageController _pageController = PageController(initialPage: 0);

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

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }
  int _currentIndex = 0;
  int _counter = 0;
  List<Widget> viewList = [
      Home(),  // page1.dart
      Graph(),
      History(),
      Setting()
      // page2.dart
    ];

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Flutter Demo")),
      body: viewList[_currentIndex],
/*      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),*/
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => Record(),
              )
          );
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      bottomNavigationBar: BottomNavyBar(
        selectedIndex: _currentIndex,
        showElevation: true,
        itemCornerRadius: 24,
        curve: Curves.easeIn,
        onItemSelected: (index) => setState(() => _currentIndex = index),
        items: <BottomNavyBarItem>[
          BottomNavyBarItem(
            icon: Icon(Icons.home),
            title: Text('ホーム'),
            activeColor: Colors.red,
            textAlign: TextAlign.center,
          ),
          BottomNavyBarItem(
            icon: Icon(Icons.show_chart),
            title: Text('グラフ'),
            activeColor: Colors.purpleAccent,
            textAlign: TextAlign.center,
          ),
          BottomNavyBarItem(
            icon: Icon(Icons.history),
            title: Text(
              '履歴',
            ),
            activeColor: Colors.pink,
            textAlign: TextAlign.center,
          ),
          BottomNavyBarItem(
            icon: Icon(Icons.settings),
            title: Text('設定'),
            activeColor: Colors.blue,
            textAlign: TextAlign.center,
          ),
        ],
      ),
    );
  }
}
よかったらシェアしてね!

コメント

コメントする

CAPTCHA


目次
閉じる