🐕

【Flutter】TabBarとTabBarViewの画面切り替えを無効化する方法

2023/10/04に公開

TabBarTabBarViewの画面切り替えを無効にする方法の備忘録。

TabBarViewのスワイプの無効化

TabBarViewphysicsプロパティにNeverScrollableScrollPhysics()をセットする。

TabBarView(
  physics: NeverScrollableScrollPhysics(), // ←これを追加する。
  controller: controller,
  children: [
    Center(child: Text('Tab 1 Content')),
    Center(child: Text('Tab 2 Content')),
    Center(child: Text('Tab 3 Content')),
  ],
),

TabBarのタップの無効化

主に方法は2つ。

IgnorePointerを使う方法

TabBarIgnorePointerで囲う。
AppBarbottomプロパティにTabBarをセットしている場合は、この方法は使えない。

IgnorePointer(
  ignoring: true,
  child: TabBar(
    controller: controller,
    tabs: [
      Tab(text: 'Tab 1'),
      Tab(text: 'Tab 2'),
      Tab(text: 'Tab 3'),
    ],
  ),
),

TabController.indexに固定したいTabのindexをセットする方法

AppBarbottomTabBarを実装する場合はこちらを使う。

Tabのタップ時に実行されるonTap内で、TabController.indexTabController.previousIndex(前回表示したタブのindex)を指定する。

TabBar(
  tabs: [
    controller: controller,
    Tab(text: 'Tab 1'),
    Tab(text: 'Tab 2'),
    Tab(text: 'Tab 3'),
  ],
  onTap: (index) {
    if (controller.indexIsChanging) { 
      controller.index = controller.previousIndex; // 前回表示したタブのindexを代入。
    } else { 
      return; 
    }
  },
),

この記事を書き始めた時点では、以下のように操作すると画面切り替えができてしまっていた↓

  1. Tab 2をタップ → 切り替わらない
  2. Tab 1をタップ → Tab2に切り替わる

TabController.previousIndexが「前回表示したタブ」ではなく 「前回タップしたタブ」 のindexだったため、↑のようなバグが生じた。
そのバグと解決方法をメインに記事を書く予定だったが、サンプルコードでは問題なくTabBarのタップを無効化できたため、要調査。

ちなみに↑のような問題が生じる場合は、TabController.previousIndexの代わりに、固定したいTabのindexの数値を直接入れる。
状態によって固定するタブを変更したい場合は、Tabのindexを状態管理オブジェクトに持たせて、それをTabController.indexに代入する。

Discussion