実装した画面のイメージ
流れはNavigationBarから各画面のファイルを呼び出して表示しています。
環境
- MacOS:13.3
- Flutter:3.19.1
ディレクトリ構成
NavigationBarから各画面のファイルを呼び出せるように構成。
lib
├── src
│ ├── screens
│ │ ├── home.dart # ホーム画面
│ │ ├── map.dart # マップ画面
│ │ ├── setting.dart # 設定画面
│ └── app.dart # ナビゲーションの実装
└── main.dart
実装
まずは各画面を実装をします。
中身としてはappbarとbodyに画面名を表示しています。
ホーム画面
lib/src/screens/home.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Home'),
),
body: const Center(
child: Text('Home画面', style: TextStyle(fontSize: 32.0))
),
);
}
}
マップ画面
lib/src/screens/map.dart
import 'package:flutter/material.dart';
class MapScreen extends StatelessWidget {
const MapScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Map'),
),
body: const Center(
child: Text('Map画面', style: TextStyle(fontSize: 32.0))),
);
}
}
設定画面
lib/src/screens/setting.dart
import 'package:flutter/material.dart';
class SettingScreen extends StatelessWidget {
const SettingScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Setting'),
),
body: const Center(
child: Text('Setting画面', style: TextStyle(fontSize: 32.0))),
);
}
}
続いてNavigationBarを使って、最初に実装した各画面を表示します。
BottomNavigationはStatefulWidgetのクラスです。
Statefulってなんぞやという方はこちらへ。
https://flutter.ctrnost.com/tutorial/tutorial05/
lib/src/app.dart
import 'package:flutter/material.dart';
import 'screens/home.dart';
import 'screens/map.dart';
import 'screens/setting.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
// Flutter公式サイトThemeを設定
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// NavigaionBarのClassを呼び出す
home: const BottomNavigation(),
);
}
}
class BottomNavigation extends StatefulWidget {
const BottomNavigation({super.key});
@override
State<BottomNavigation> createState() => _BottomNavigationState();
}
class _BottomNavigationState extends State<BottomNavigation> {
// 各画面のリスト
static const _screens = [
HomeScreen(),
MapScreen(),
SettingScreen()
];
// 選択されている画面のインデックス
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return Scaffold(
body: _screens[_selectedIndex],
// 本題のNavigationBar
bottomNavigationBar: NavigationBar(
// タップされたタブのインデックスを設定(タブ毎に画面の切り替えをする)
onDestinationSelected: (int index) {
setState(() {
_selectedIndex = index;
});
},
// 選択されているタブの色(公式サイトのまま黄色)
indicatorColor: Colors.amber,
// 選択されたタブの設定(設定しないと画面は切り替わってもタブの色は変わらないです)
selectedIndex: _selectedIndex,
// タブ自体の設定(必須項目のため、書かないとエラーになります)
destinations: const <Widget>[
NavigationDestination(
selectedIcon: Icon(Icons.home),
icon: Icon(Icons.home_outlined),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.map),
label: 'Map',
),
NavigationDestination(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
)
);
}
}
最後にアプリを表示するためにmain()からMyapp()を呼び出します。
lib/main.dart
import 'package:flutter/material.dart';
import 'src/app.dart';
void main() {
runApp(const MyApp());
}
まとめ
Flutterで何か作るために、とりあえずアプリのガワを作ろう。
そして今回はBottomタブと画面の切り替えをできるようにしました。
元々はBottomNavigationBar
を使おうと思っていましたが、新しくMaterial3のデザイン用にNavigationBar
が登場したようなので、こちらを採用してみました。
参考文献