Flutterでアプリ下部にナビゲーションメニューを設置するサンプル
はじめに
色々なスマホアプリでページ下部にメニューがあり、タップすると画面が切り替わる機能ががあります。ボトムナビゲーションメニュー等といい、Flutterでは、BottomNavigationBar
とPageView
を使うことで簡単に実装できます。この記事では、これらを使った簡単な例をまとめます。
できるようになること
以下のGIF画像のように、アプリ下部にナビゲーションメニューがあり、タップしたり水平方向にページをスワイプすることでページを切り替えることができます。
デモのサンプルコード
上記のGIF画像のデモのサンプルコードを以下に載せます。以下のコードの元はflutter create
で作成したカウンターアプリです。BottomNavigationBar
とPageView
に関連する部分にはコメントを記載しています。
main.dartのコード
まずはじめにmain.dart
です。
import 'package:flutter/material.dart';
import './pages/BookScreen.dart';
import './pages/CakeScreen.dart';
import './pages/CloudScreen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'BottomNav',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
// SingleTickerProviderStateMixinを使用。後述
class _MyHomePageState extends State
with SingleTickerProviderStateMixin {
// ページ切り替え用のコントローラを定義
PageController _pageController;
// ページインデックス保存用
int _screen = 0;
// ページ下部に並べるナビゲーションメニューの一覧
List myBottomNavBarItems() {
return [
BottomNavigationBarItem(
icon: Icon(Icons.book),
title: const Text('Book'),
),
BottomNavigationBarItem(
icon: Icon(Icons.cloud),
title: const Text('Cloud'),
),
BottomNavigationBarItem(
icon: Icon(Icons.cake),
title: const Text('Cake'),
),
];
}
void initState() {
super.initState();
// コントローラ作成
_pageController = PageController(
initialPage: _screen, // 初期ページの指定。上記で_screenを1とすれば2番目のページが初期表示される。
);
}
void dispose() {
// コントローラ破棄
_pageController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[900],
// Appbar
appBar: AppBar(
backgroundColor: Colors.blue[900],
title: Text(
'BottomNav',
style: TextStyle(fontSize: 16),
),
),
// ),
// ページビュー
body: PageView(
controller: _pageController,
// ページ切り替え時に実行する処理
// PageViewのonPageChangedはページインデックスを受け取る
// 以下ではページインデックスをindexとする
onPageChanged: (index) {
setState(() {
// ページインデックスを更新
_screen = index;
});
},
// ページ下部のナビゲーションメニューに相当する各ページビュー。後述
children: [
BookScreen(),
CloudScreen(),
CakeScreen(),
]),
// ページ下部のナビゲーションメニュー
bottomNavigationBar: BottomNavigationBar(
// 現在のページインデックス
currentIndex: _screen,
// onTapでナビゲーションメニューがタップされた時の処理を定義
onTap: (index) {
setState(() {
// ページインデックスを更新
_screen = index;
// ページ遷移を定義。
// curveで指定できるのは以下
// https://api.flutter.dev/flutter/animation/Curves-class.html
_pageController.animateToPage(index,
duration: Duration(milliseconds: 300), curve: Curves.easeOut);
});
},
// 定義済のナビゲーションメニューのアイテムリスト
items: myBottomNavBarItems(),
),
);
}
}
SingleTickerProviderStateMixin
を使用していますが、これについては以下が大変参考になりました。
また、ページ切替時のアニメーションの挙動については、animateToPage
のオプションで指定しています。Duration
で遷移にかける時間、curve
で挙動を指定できます。このcurve
については、以下の公式ドキュメントにどのようなものを指定できてそれぞれどのような挙動かまとまっています。
ナビゲーションメニューに対応するビューのコード
あとは、アプリ下部のナビゲーションメニューに対応するページビューを3つ用意します。ここでは、適当にpages
という名前のディレクトリをlib
配下に作成し、そこにpages/BookScreen.dart
、pages/CloudScreen.dart
、pages/CakeScreen.dart
を作成しました。なお、これら3つはほぼ全て同じ内容で色やアイコンを変更しているだけです。
import 'package:flutter/material.dart';
class BookScreen extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[100],
// Appbar
appBar: AppBar(
backgroundColor: Colors.green[100],
title: Text(
'Book',
style: TextStyle(fontSize: 16),
),
),
body: Center(child: Icon(Icons.book)));
}
}
以下はpages/CloudScreen.dart
です。
import 'package:flutter/material.dart';
class CloudScreen extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[100],
// Appbar
appBar: AppBar(
backgroundColor: Colors.blue[100],
title: Text(
'Cloud',
style: TextStyle(fontSize: 16),
),
),
body: Center(child: Icon(Icons.cloud)));
}
}
以下はpages/CakeScreen.dart
です。
import 'package:flutter/material.dart';
class CakeScreen extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.pink[100],
// Appbar
appBar: AppBar(
backgroundColor: Colors.pink[100],
title: Text(
'Cake',
style: TextStyle(fontSize: 16),
),
),
body: Center(child: Icon(Icons.cake)));
}
}
まとめ
アプリ下部に表示する基本的なナビゲーションメニューを実装しました。
関連記事
- 公開日:2022/08/30 更新日:2022/08/30
FlutterアプリでAndroid StudioのGenerate Signed Bundle/APKが表示されない時の対処法
FlutterアプリをGoogle Play Storeに公開するためにAndroid Studioを使ってアップロード鍵を生成しようとしたところ、公式ドキュメントに書かれている「Build」→「Generate Signed Bundle/APK」というメニューが見つかりませんでした。この解決法をメモします。
- 公開日:2022/08/15 更新日:2022/08/15
webview_flutterを使ってFlutterアプリ内でWebページを開く
FlutterでURLをタップした時にアプリ内でそのURLのWebページを開く方法についてまとめます。この記事では、Flutter公式のプラグインであるwebview_flutterを使用した実装例をメモします。
- 公開日:2022/08/14 更新日:2022/08/14
FlutterでURLへのリンクを作成してアプリ外でWebページを開く
FlutterでURLをタップしたらブラウザが開いてそこでURL先を表示したい場合があります。この記事では、Flutter公式のプラグインを使用した実装例をメモします。
- 公開日:2019/12/03 更新日:2019/12/03
Android App Bundleを実機にインストールして試すために使うbundletoolの使い方
Flutterなどで開発したAndroidアプリを自分の手元にある実機にインストールして試したい場合はbundletoolを使用するよう公式ドキュメントに記載されています。ただ、常識であるためなのか詳しい使い方が書かれておらず戸惑ったのでメモしておきます。
- 公開日:2019/12/02 更新日:2019/12/02
Flutterでアプリの復帰やサスペンドを検出して処理を実行する
Flutterで開発したアプリが復帰した時やサスペンドした時を検出して任意の処理を実行するための手順をまとめます。