Flutter

【Flutter】BottomNavigationBarとuseStateで簡単タブメニュー実装

最終更新から4年以上たっています。ライブラリのバージョンや手順が変わっている可能性があります。

こんにちは。趣味グラマのNobu(@nm_aru)です。

Flutterでタブメニューを作成する時に、BottomNavigationBarを使うと思います。

その際、今どのタブがアクティブかを管理するために、StatefulWidgetのstateを使う方法がよく例示されます。公式ドキュメントでもそうなってますね。

BottomNavigationBar class - material library - Dart API
API docs for the BottomNavigationBar class from the material library, for the Dart programming language.

ただ、StatefulWidgetは作るのが面倒なので、今回はflutter_hooksのuseStateを使う事で超簡単に実装してみました。

app.dart
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

void main() {
  runApp(const ProviderScope(child: App()));
}

class App extends HookWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final tabIndex = useState(0);

    return MaterialApp(
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.light,
      home: Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          onTap: (int selectIndex) => tabIndex.value = selectIndex,
          items: const [
            BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
            BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings')
          ],
          currentIndex: tabIndex.value,
        ),
        body: [const SamplePage('Home'), const SamplePage('Settings')][tabIndex.value],
      ),
    );
  }
}

class SamplePage extends StatelessWidget {
  const SamplePage(this._title, {Key? key}) : super(key: key);

  final String _title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: Center(
        child: Text("This screen is $_title."),
      ),
    );
  }
}

もっとしっかり実装する場合は、各タブを表現したenumを作って、StateProviderを使ったりもあります。

まとめ

hooksのおかげで、StatefulWidgetを使わなくても良いシーンが増えたので、非常にありがたいパッケージです。

made with Flutter

この記事を書いた人がつくったアプリ

Flutter の記事

コメントの受け付けは終了しました。ご意見・ご質問は X(@nm_aru)へどうぞ。