この記事では、Flutterの手元のナビゲーションバーBottomNabigationBarについて書いていきます。
サンプル①
lib/main
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
// Riverpod を使うために ProviderScope でアプリを包む
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
// 選択中のタブインデックスを管理する Provider
final tabIndexProvider = StateProvider<int>((ref) => 0);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MainPage(),
);
}
}
// StatelessWidget の代わりに Riverpod の ConsumerWidget を継承
class MainPage extends ConsumerWidget {
const MainPage({super.key});
// 各タブで表示する画面リスト
static const List<Widget> _pages = [
Center(child: Text('ホーム画面', style: TextStyle(fontSize: 24))),
Center(child: Text('検索画面', style: TextStyle(fontSize: 24))),
Center(child: Text('設定画面', style: TextStyle(fontSize: 24))),
];
@override
Widget build(BuildContext context, WidgetRef ref) {
// 現在選択されているタブ番号を監視
final selectedIndex = ref.watch(tabIndexProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Stateless + Riverpod の例'),
),
// 選択中のインデックスの画面を表示
body: _pages[selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: selectedIndex,
// タップ時に Provider の値を更新(StatefulWidget の setState 不要)
onTap: (index) {
ref.read(tabIndexProvider.notifier).state = index;
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'ホーム',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: '検索',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: '設定',
),
],
),
);
}
}pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_riverpod: ^2.5.0サンプル②
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const MainPage(),
);
}
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
// 現在選択されているタブのインデックス
int _selectedIndex = 0;
// 各タブで表示する画面のリスト
final List<Widget> _pages = const [
Center(child: Text('ホーム画面', style: TextStyle(fontSize: 24))),
Center(child: Text('検索画面', style: TextStyle(fontSize: 24))),
Center(child: Text('設定画面', style: TextStyle(fontSize: 24))),
];
// タブがタップされたときの処理
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar の例'),
),
// 選択されたインデックスに応じた画面を表示
body: _pages[_selectedIndex],
// 下部ナビゲーションバーの設定
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex, // 現在選択中のインデックス
onTap: _onItemTapped, // タップ時のイベント
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'ホーム',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: '検索',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: '設定',
),
],
),
);
}
}手元のナビゲーションバーを設定するには
手元のナビゲーションバーを設定するには
bottomNavigationBarをつかいます。
サンプル①、②どちらでも実行できます。
コードの解説
ConsumerWidget class - flutter_riverpod library - Dart API
API docs for the ConsumerWidget class from the flutter_riverpod library, for the Dart programming language.
