LoginSignup
0
2

More than 3 years have passed since last update.

flutter_blocを使ってみる その6 - BLoCでTabViewを作成する

Posted at

BLoCでTabViewを作成する方法

FlutterでTabViewを作るときはDefaultTabControllerを使うことが多いですが、BLoCを使うこともできます。

flutter_blocを用いる場合、以下のように作ります。

  • Tab情報をenum等のStateとしてして持つ。
  • Tabが選択された際にEventをBLoCに送る。EventはTab情報(State)をプロパティとして持つ。
  • Eventを受け取ったBlocが選択されたTabをStateとして通知する。
  • View側がStateを受け取り、選ばれたTabの内容を描画する。

実際のコード

flutter_blocを使って以下のようなコードを作成します。

BLoC

// Bloc
// BlocState
enum AppTab { a, b }

// BlocEvent
abstract class TabEvent extends Equatable {
  const TabEvent();
}

class UpdateTab extends TabEvent {
  final AppTab tab;

  const UpdateTab(this.tab);

  @override
  List<Object> get props => [tab];

  @override
  String toString() => 'UpdateTab { tab: $tab }';
}

// Bloc
class TabBloc extends Bloc<TabEvent, AppTab> {
  TabBloc() : super(AppTab.a);

  @override
  Stream<AppTab> mapEventToState(TabEvent event) async* {
    if (event is UpdateTab) {
      yield event.tab;
    }
  }
}

View

void main() {
  runApp(MyApp());
}


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider<TabBloc>(
        create: (context) => TabBloc(),
        child: TabBlocPage(),
      ),
    );
  }
}

class TabBlocPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TabBloc, AppTab>(
      builder: (context, activeTab) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('TabBlocExample'),
          ),
          // 選ばれたTab(State)によって描画する
          body: activeTab == AppTab.a ? TabA() : TabB(),
          bottomNavigationBar: TabSelector(
            activeTab: activeTab,
            // ユーザーが選んだTabをEventに持たせて送るFunctionをTabSelectorのメソッドに割り当てる
            onTabSelected: (tab) => BlocProvider.of<TabBloc>(context).add(UpdateTab(tab)),
          ),
        );
      },
    );
  }
}

// TabView
class TabA extends StatelessWidget {
  const TabA({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(child: Text('TabA')),
    );
  }
}

class TabB extends StatelessWidget {
  const TabB({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(child: Text('TabB')),
    );
  }
}

// BottomNavigationBar
class TabSelector extends StatelessWidget {
  const TabSelector({
    Key key,
    this.activeTab,
    this.onTabSelected,
  }) : super(key: key);
  final AppTab activeTab;
  final Function(AppTab) onTabSelected;

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.circle),
          label: 'TabA',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.crop_square),
          label: 'TabB',
        ),
      ],
      currentIndex: AppTab.values.indexOf(activeTab),
      selectedItemColor: Colors.amber[800],
      // ユーザーがTabを選択した際にBLoCにEventを送る
      onTap: (index) => onTabSelected(AppTab.values[index]),
    );
  }
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2