Flutter

選択されたタブの位置によってウィジェットの表示&非表示を制御する

Flutterで、選択されたタブの位置を把握して、タブごとにウィジェットのふるまいを変えたい場合の処理をまとめておきます。

実装したかったこと

左側のタブが選択されたときはFloatingActionButtonを表示して、右側のタブが選択されたときは表示しないこと。

ソースコード

参考にした公式ドキュメント

タブを表示する

TabContollerクラスの公式ドキュメントをもとにタブ表示のウィジェットを作成します。

クラスの作成。タブコントローラを使うために、SingleTickerProviderStateMixinを継承します。

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {

タブリストの作成。二つのタブを作成します。

static const List<Tab> myTabs = <Tab>[
  Tab(text: '左'),
  Tab(text: '右'),
];

タブコントローラを宣言(あとで初期化するのでlate)

late TabController _tabController;

initStateで初期化

@override
void initState() {
  super.initState();
  _tabController = TabController(vsync: this, length: myTabs.length);
}

画面終了時にタブコントローラも終了

@override
void dispose() {
  _tabController.dispose();
  super.dispose();
}

AppBarにタブを表示

appBar: AppBar(
  bottom: TabBar(
    labelStyle: const TextStyle(fontSize: 28.0),
    controller: _tabController,
    tabs: myTabs,
  ),
),

タブが選択されたときに表示する画面部分(body)を書きます。

body: TabBarView(
  controller: _tabController,
  children: myTabs.map((Tab tab) {
    final String label = tab.text!;
    return Center(
      child: Text(
        '$labelのタブだよ',
        style: const TextStyle(fontSize: 36),
      ),
    );
  }).toList(),
),

選択されたタブの位置を把握しふるまいを定義する

initStateにListnerを追加しタブの選択状況を把握します。

@override
void initState() {
  super.initState();
  _tabController = TabController(vsync: this, length: myTabs.length);
  _tabController.addListener(selectedTabChanged);
}

FloatingActionButtonの表示有無を決めるbool変数を用意します。デフォルトは表示(true)。

bool _floatingActionButtonVisibility = true;

選択されたタブが変化したときのふるまいを定義します。

selectedTabChanged() {
  if (!_tabController.indexIsChanging) {
    switch (_tabController.index) {
      case 0:
        _floatingActionButtonVisibility = true;
        break;
      case 1:
        _floatingActionButtonVisibility = false;
        break;
    }
    setState(() {});
  }
}

タブコントローラーのindexが変化したときに、index番号にもとづいて処理を書きます。indexが0、つまり左側のタブならtrue、右側の場合はfalseとしました。

以上、選択されたタブの位置によってウィジェットの表示&非表示を制御する処理の説明です。

おわり。