Re:birth エンジニアリング

Flultterとテックブログと時々iOS

FlutterでSegmentController的なUIをTabBarViewを使って実装する

本日はFlutterのTabBarTabBarViewについて学習します。 iOSでいえばスマートニュースやグノシーみたいなニュース系アプリに使われているトップ画面のメニューバーみたいなUIを実現できます。

TabBarの基本的な書き方

TabBarの基本的な書き方は次の通りです。

TabBar(
          controller: [TabControllerのインスタンス],
          tabs: [Tabのリスト],
        ),

api.flutter.dev

Tabの基本的な書き方

上記で登場したTabクラスのインスタンスの作成方法は次の通りです。

Tab(text: [Textウィジェット])

これでTabの部分のインスタンスが作成できます。 非常に簡単ですね。

api.flutter.dev

TabBarViewの基本的な書き方

次にTabBarViewの基本的な書き方です。

TabBarView(
        controller: [TabControllerのインスタンス],
        children: [ウィジェットのインスタンス],
      )

このように見るとTabBarとTabBarViewにはTabControllerというインスタンスが必要なのが分かります。

api.flutter.dev

TabController の基本形

では、共通して使うTabController について見ていきます。 Controllerという命名なくらいなのでTabControllerはTabとTabBarViewの架け橋的な存在なのが分かりますね。

TabController(
      vsync: [TickerProviderのインスタンス],
      length: [int値]
    )

ここで見慣れないTickerProviderというクラスが初めて登場します。 Providerという概念はFlutterで開発する上で重要らしいので別の機会に学習しますので置いといて、 TickerProviderとはアニメーションのコールバックに用いれるTickerクラスを生成するものらしいです。 これによって生成されるTabBarViewの部分が横スクロールすることを実現させているそうです。

なので、Flutter のTabBarViewは横スクロールがデフォルトで実装されているぽいですね。

api.flutter.dev

TabBarのサンプルソースコード

それではTabBar の練習用のサンプルソースコードを書いていこうと思います。

main.dart

import 'package:flutter/material.dart';
import 'package:practice_app/custom_tabbar.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  final title = 'TabBarのサンプルコード';
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: true,
      title: 'TabBar App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
        primaryColor: const Color(0xff2196f3),
        accentColor: const Color(0xff2196f3),
        canvasColor: const Color(0xfffafafa),
      ),
      home: CustomTabBar(),
    );
  }
}

custom_tabbar.dart

import 'package:flutter/material.dart';

class CustomTabBar extends StatefulWidget {
  @override
  _CustomTabBarState createState() => _CustomTabBarState();
}

class _CustomTabBarState extends State<CustomTabBar> with SingleTickerProviderStateMixin {

  final List<Tab> tabs = [
    Tab(text: 'Home'),
    Tab(text: 'News'),
    Tab(text: 'Setting')
  ];

  TabController _tabController;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TabBar'),
        bottom: TabBar(
          controller: _tabController,
          tabs: tabs,
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: createTabs(tabs),
      ),
    );
  }

  List<Widget> createTabs(List<Tab> tabs) {
    final widgets = tabs.map((Tab tab) {
      return Center(
        child: Text(
          tab.text + '画面',
          style: TextStyle(
            fontSize: 30.0,
            color: Colors.blue
          ),
        ),
      );
    }).toList();
    return widgets;
  }
}

こちらをビルドして実行すると次のような画面が表示されます。

Home News Setting
f:id:qed805:20200209202313p:plain
home画面
f:id:qed805:20200209202332p:plain
News画面
f:id:qed805:20200209202348p:plain
Setting画面

このように3画面が表示されます。 それぞれのタブをタップするとスクロールしてそれぞれの画面に遷移しているように見えます。 これでTabBarViewが実装できたことを確認できました。

本日はTabBarViewの基本的な使い方について学習しました。