Flutterの手元のナビゲーションバーBottomNabigationBar

Flutter/Dart

この記事では、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.
タイトルとURLをコピーしました