Flutter footer作成 ３点

# Footer作成３点

## 通常footer

```dart

int _selectedIndex = 0;
final List<Widget> rootWidgetIcons = [const Home(), const Setting(),];

void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: rootWidgetIcons[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Setting'),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
```

### 感想
- 基本的にこれでいい（Scaffold便利）
- NavigationBarを固定したまま画面遷移する場合はカスタムが必要
- よくある「iOSっぽい挙動」でみたいなときにちょっと困る

## iOSっぽいもの

```dart
final List<Widget> rootWidgetIcons = [const Home(), const Setting(),];

@override
Widget build(BuildContext context) {
  return CupertinoPageScaffold(
      child: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                  icon: Icon(Icons.home), label: 'Home'),
              BottomNavigationBarItem(
                  icon: Icon(Icons.settings), label: 'Setting'),
            ],
          ),
          tabBuilder: (context, index) {
            return CupertinoTabView(builder: (context) {
              return Container(
                  child: rootWidgetIcons[index]
              );
            });
          }),
    );
  );
}
```

### 感想
- NavigationBarを固定したまま画面遷移することが出来る
- 例で記載しているHomeやSettingは、SafeArea内で構成することで、TitleBar, BottomNavigationBar間で表示が可能、しかしDropDownMenuなど一部の機能がBottomNavigationBarの下に潜り込んでしまった。そのため使用していない。

> 解決方法あるらしい(未検証)
https://github.com/flutter/flutter/issues/22917

## ライブラリ仕様

https://pub.dev/packages/persistent_bottom_nav_bar

```dart
class Footer extends StatefulWidget {
  const Footer({Key? key}) : super(key: key);

  @override
  _Footer createState() => _Footer();
}

class _Footer extends State {
  late PersistentTabController _controller;

  @override
  void initState() {
    super.initState();
    _controller = PersistentTabController(initialIndex: 0);
  }

  List<Widget> _buildScreens() {
    return [const Home(), const Setting()];
  }

  List<PersistentBottomNavBarItem> _navBarsItems() {
    return [
      PersistentBottomNavBarItem(
        icon: const Icon(Icons.home),
        title: 'ホーム',
        activeColorPrimary:
            Theme.of(context).bottomNavigationBarTheme.selectedItemColor!,
        inactiveColorPrimary: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: const Icon(Icons.settings),
        title: '設定',
        activeColorPrimary:
            Theme.of(context).bottomNavigationBarTheme.selectedItemColor!,
        inactiveColorPrimary: CupertinoColors.systemGrey,
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PersistentTabView(
      context,
      controller: _controller,
      screens: _buildScreens(),
      items: _navBarsItems(),
      confineInSafeArea: true,
      backgroundColor: Theme.of(context)
          .bottomNavigationBarTheme
          .backgroundColor!,
      handleAndroidBackButtonPress: true,
      resizeToAvoidBottomInset: true,
      stateManagement: true,
      hideNavigationBarWhenKeyboardShows: true,
      popAllScreensOnTapOfSelectedTab: true,
      popActionScreens: PopActionScreensType.all,
      itemAnimationProperties: const ItemAnimationProperties(
        duration: Duration(milliseconds: 200),
        curve: Curves.ease,
      ),
      screenTransitionAnimation: const ScreenTransitionAnimation(
        animateTabTransition: false,
        curve: Curves.ease,
        duration: Duration(milliseconds: 200),
      ),
      navBarStyle: NavBarStyle.style6, // 利用したいものを選択
    ));
  }
}

```

### 感想
- NavigationBarを固定したまま画面遷移することが出来る
- navBarStyleでいくつか選べる(item数制限があるものもあります)
- 欠点としては遷移時TitleBarも動いてしまう。完全iOSに寄せるなら中のコンテンツだけ


## まとめ
この３点の中では僕はラ３つめのイブラリを使用して実装してます
他にもおすすめや、アドバイス等あればご教授願います