TabBar

TabBar

「TabBar」を使うことで、簡単にヘッダーにタブバーを作ることができるようになります。
今回は、「TabBar」を使ったサンプルを説明していきます。

class _MainPageState extends State<MainPage> {

  final _tab = <Tab> [
    Tab( text:'Car', icon: Icon(Icons.directions_car)),
    Tab( text:'Bicycle', icon: Icon(Icons.directions_bike)),
    Tab( text:'Boat', icon: Icon(Icons.directions_boat)),
  ];

  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tab.length,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('TabBar'),
          bottom: TabBar(
            tabs: _tab,
          ),
        ),
        body: TabBarView(
            children: <Widget> [
              TabPage(title: 'Car', icon: Icons.directions_car),
              TabPage(title: 'Bicycle', icon: Icons.directions_bike),
              TabPage(title: 'Boat', icon: Icons.directions_boat),
            ]
        ),
      ),
    );
  }
}

class TabPage extends StatelessWidget {

  final IconData icon;
  final String title;

  const TabPage({Key key, this.icon, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final TextStyle textStyle = Theme.of(context).textTheme.display1;
    return Center(
      child:Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Icon(icon, size: 64.0, color: textStyle.color),
          Text(title, style: textStyle),
        ],
      ),
    );
  }
}
TabBar

  • isScrollableをtrueにするとタブをスクロールできるようになります。
  • indicatorColorはタブ下に表示さている線の色を指定できます。
  • indicatorWeightはタブ下に表示さている線の太さをしていてきます。
  • indicatorPaddingはタブ下に表示さている線にPaddingを与えることができ、指定は「EdgeInsets」で行います。
  • indicatorSizeはタブ下に表示さている線に対して、以下二つの要素どちらかによって幅が変わります。
    • TabBarIndicatorSize.tabはタブと同じ幅
    • TabBarIndicatorSize.tabはラベルと同じ幅
  • indicatorはタブ下に表示さている線に「Decoration」を使ってデザインの変更ができます。
  • labelColorは表示しているラベルの色
  • labelStyleはラベルのスタイルを「TextStyle」で指定できます。
  • labelPaddingはラベルのPaddin要素を指定します。
  • unselectedLabelColorは未選択状態でのアイコンラベルの表示色を指定できます。
  • unselectedLabelStyleは未選択状態でのラベルのスタイルを「TextStyle」で指定できます。

「TabBar」を作るときは、「TabBar」、「TabBarView」に「TabController」クラスを設定するか、「DefaultTabController」の子要素としてそれぞれを作成する方法の2種類があります。 まずは、「DefaultTabController」での作成方法をみていきましょう。

return DefaultTabController(
  length: _tab.length,
  child: Scaffold(
    appBar: AppBar(
      title: const Text('TabBar'),
      bottom: TabBar(
        tabs: _tab,
      ),
    ),
    body: TabBarView(
      children: <Widget> [
        TabPage(title: 'Car', icon: Icons.directions_car),
        TabPage(title: 'Bisycle', icon: Icons.directions_bike),
        TabPage(title: 'Boat', icon: Icons.directions_boat),
      ]
    ),
  ),
);

「DefaultTabController」には必ず、「TabBar」で表示するタブ数をlengthに設定しておかなければなりません。

return DefaultTabController(
  length: _tab.length,
  child: Scaffold(
    appBar: AppBar(

次に「AppBar」のbottomに「TabBar」クラスを定義して、表示するタブのリストを渡します。

appBar: AppBar(
  title: const Text('TabBar'),
  bottom: TabBar(
    tabs: _tab,
  ),
),

今回は「Tab」の一覧は_tab変数に定義しておきます。

  final _tab = <Tab> [
    Tab( text:'Car', icon: Icon(Icons.directions_car)),
    Tab( text:'Bisycle', icon: Icon(Icons.directions_bike)),
    Tab( text:'Boat', icon: Icon(Icons.directions_boat)),
  ];

これで、タブの表示ができましたが、画面表示の切り替えも確認しましょう。
bodyに「TabBarView」クラスを定義し、表示する画面となるウィジェットの一覧を渡します。
今回は「TabPage」という画面ウィジェットを作ってあるので、一覧として設定して完成です。

body: TabBarView(
  children: <Widget> [
    TabPage(title: 'Car', icon: Icons.directions_car),
    TabPage(title: 'Bisycle', icon: Icons.directions_bike),
    TabPage(title: 'Boat', icon: Icons.directions_boat),
  ]
),

TabController

今度は「TabController」での書き方をみてみましょう。

class _MainPageState extends State<MainPage> with SingleTickerProviderStateMixin {

  TabController _tabController;

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

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

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('TabBar'),
        bottom: TabBar(
          controller: _tabController,
          tabs: _tab,
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: <Widget> [
          TabPage(title: 'Car', icon: Icons.directions_car),
          TabPage(title: 'Bisycle', icon: Icons.directions_bike),
          TabPage(title: 'Boat', icon: Icons.directions_boat),
        ]
      ),
    );
  }
}

このように「TabController」を使うときは必ずinitStateメソッドで、初期化し、disposeメソッドで破棄を書いてください。
こうすることで、_MainPageStateの作成、破棄と同じタイミングで「TabController」も作成、破棄が行われるようになります。

  TabController _tabController;

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

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

次に「TabBar」、「TabBarView」それぞれに「TabController」を設定することで、タブが動作するようになるので、完成です。

bottom: TabBar(
  controller: _tabController,
  tabs: _tab,
),
body: TabBarView(
  controller: _tabController,
  children: <Widget> [
    TabPage(title: 'Car', icon: Icons.directions_car),
    TabPage(title: 'Bisycle', icon: Icons.directions_bike),
    TabPage(title: 'Boat', icon: Icons.directions_boat),
  ]
),