使用選項卡是遵循 Material Design 指南的應用程式中的常見模式。Flutter 提供了一種方便的方式,作為其 material 庫的一部分來建立選項卡布局。

本食譜透過以下步驟建立一個選項卡示例;

  1. 建立一個 TabController
  2. 建立選項卡。
  3. 為每個選項卡建立內容。

1. 建立一個 TabController

#

為了使選項卡正常工作,你需要保持選定的選項卡和內容部分同步。這是 TabController 的職責。

手動建立一個 TabController,或透過使用 DefaultTabController widget 自動建立一個。

使用 DefaultTabController 是最簡單的選擇,因為它會建立一個 TabController 並使其可用於所有後代 widget。

dart
return MaterialApp(
  home: DefaultTabController(length: 3, child: Scaffold()),
);

2. 建立選項卡

#

選擇選項卡時,它需要顯示內容。你可以使用 TabBar widget 建立選項卡。在此示例中,建立一個包含三個 Tab widget 的 TabBar 並將其放置在 AppBar 中。

dart
return MaterialApp(
  home: DefaultTabController(
    length: 3,
    child: Scaffold(
      appBar: AppBar(
        bottom: const TabBar(
          tabs: [
            Tab(icon: Icon(Icons.directions_car)),
            Tab(icon: Icon(Icons.directions_transit)),
            Tab(icon: Icon(Icons.directions_bike)),
          ],
        ),
      ),
    ),
  ),
);

預設情況下,TabBar 會在 widget 樹中查詢最近的 DefaultTabController。如果你是手動建立 TabController,請將其傳遞給 TabBar

3. 為每個選項卡建立內容

#

現在你有了選項卡,當選擇選項卡時顯示內容。為此,使用 TabBarView widget。

dart
body: const TabBarView(
  children: [
    Icon(Icons.directions_car),
    Icon(Icons.directions_transit),
    Icon(Icons.directions_bike),
  ],
),

互動示例

#
import 'package:flutter/material.dart';

void main() {
  runApp(const TabBarDemo());
}

class TabBarDemo extends StatelessWidget {
  const TabBarDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: [
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: const Text('Tabs Demo'),
          ),
          body: const TabBarView(
            children: [
              Icon(Icons.directions_car),
              Icon(Icons.directions_transit),
              Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );
  }
}