【Flutter】ニューモフィックデザインでTabBarを作成する

##はじめに
[flutter_neumorphic](https://pub.dev/packages/flutter_neumorphic)というパッケージを使うと,簡単にアプリの中にニューモフィックデザインを取り入れることができます。
![スクリーンショット 2020-10-10 10.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/88ff013b-ab22-4297-9cb3-7f1bdafdd2d0.png)
この記事ではこのパッケージで用意されていないタブビューを作成する手順を記したいと思います。

##この記事を読んでできること

<img  width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/c801a592-b9d7-d53d-f4fb-ff38971b8f10.png"> <img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/4d12c74e-4bb7-299c-e61b-9798bfbd5d01.png">
画像のようにタブ作成しボタンを押すことで画面を切り替えられるようにします。画像ではText("A")を表示しているだけですが,入力フォームなどなんでも表示することができます。

##1.NeumorphicButtonを配置する
[flutter_neumorphic](https://pub.dev/packages/flutter_neumorphic)にはニューモフィックデザインのボタンが用意されているので,それを作成します。

```Dart
body: Center(
          child: NeumorphicButton(
            style: NeumorphicStyle(
              shape: NeumorphicShape.concave
            ),
            onPressed: (){print("ボタンが押された");},
            child: Text("ボタン"),
          ),
        )
```

これだけで作成できます。なんて素晴らしいパッケージなんだ！

##2.AppBarと配置されるビューを準備し,StackとOffStageに入れる。
OffStageを使うことでbool型のパラメータをもとに,falseの時は表示,trueの時は表示といった処理ができます。また,StackはWidgetを重ねることができるため,StackとOffStageを組み合わせることでタブビューを作成することができます。
StackとOffStageの使い方については[別のところ](https://qiita.com/Hyperbolic_____/items/6d8f48e5250bc590470e)で記事にしています。

```Dart
appBar: AppBar(
          backgroundColor: Color.fromRGBO(220, 231, 240, 1),
            title: Stack(
              children: <Widget>[
                Offstage(
                  offstage: !bShow,
                  child: Container(
                    child: Text("A",
                    style: TextStyle(color: Colors.black)),
                  )
              ),
                Offstage(
                  offstage: !aShow,
                    child: Container(
                      child: Text("B",
                          style: TextStyle(color: Colors.black)),
                    )
                ),
              ],
            )

        ),
```

上のコードはaShow,bShowというbool型の値によって,AppBarをそれぞれ入れ替えることができるようにしています。aShow,bShowはタブビューのボタンを押すことでそれぞれ値を反転させればタブビューを表現できます。
##3.タブビューのボタンを入れ替えることで真偽値を入れ替えるようにする。
1で作ったボタンのonPressed()にaShow,bShowを反転する処理を書きます。また,ボタンをそれぞれ作成し,Rowに入れます。

```Dart



Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    NeumorphicButton(
                      child: Container(
                        width: 30,
                        height: 30,
                        child: Text("A")
                      ),
                      onPressed: (){
                        aShow = !aShow;
                        bShow = !bShow;
                    },

                    ),
                    NeumorphicButton(
                      child: Container(
                        width: 30,
                        height: 30,
                        child: Text("B")
                      ),
                      onPressed: (){
                        aShow = !aShow;
                        bShow = !bShow;
                      },

                    ),
                  ],
                )
```

##ソースコード
上のニューモフィックデザイン取り入れたものとは異なりますが,コピペしてそのまま使えるコードを置いておきます。

```Dart
import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool showRed = false;
  bool showBlue = true;
  bool showGreen = true;
  
  void showChange(String color) {  
    switch(color){
      case 'red':
        print("赤");
        setState(() {
        showRed = false;
        showBlue = true;
        showGreen = true;
          });
        break;
      case 'blue':
          print("青");
        setState(() {
        showRed = true;
        showBlue = false;
        showGreen = true;
          });
        break;
      case 'green':
         print("緑");
        setState(() {
        showRed = true;
        showBlue = true;
        showGreen = false;
          });
      break;
    }
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
            title: Center(
              child: Stack(
                children: <Widget>[
                  Offstage(
                      offstage: showRed,
                      child: Text("赤"),
                          ),
                  Offstage(
                      offstage: showBlue,
                      child: Text("青"),
                          ),
                  Offstage(
                      offstage: showGreen,
                      child: Text("緑"),
                         ),
                  ],
                ),
            ),
          ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(5.0),
              child: Stack(
              children: <Widget>[
            Offstage(
              offstage: showRed,
              child: Red()
              ),
            Offstage(
              offstage: showBlue,
              child: Blue()
              ),
                Offstage(
              offstage: showGreen,
              child: Green()
              ),
                
              ],
            ),
              
              ),
            Spacer(),
            tabButton(),
            ],
          ),
         ),
        ),
      );
  }
  Widget tabButton() {
    
    return Container(
      //final Size size = MediaQuery.of(context).size;
      width: 500,
      height: 100,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Container(
                 width: 100,
                 height: 100,
                 child: RaisedButton(
                   child: Text("赤"),
                   onPressed: (){
                     showChange('red');
                     }
                 ),
            ),
          Container(
                 width: 100,
                 height: 100,
                 child: RaisedButton(
                   child: Text("青"),
                   onPressed: (){
                     showChange('blue');
                     }
                 ),
            ),
          Container(
                 width: 100,
                 height: 100,
                 child: RaisedButton(
                   child: Text("緑"),
                   onPressed: (){
                     showChange('green');
                     }
                 ),
            ),
        ],
        ),
      );
  }
}

class Red extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 400,
      height: 400,
      color: Colors.red,
      child: (
         Text("Red")
        ),
      );
  }
}

class Blue extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 400,
      height: 400,
      color: Colors.blue,
      child: (
         Text("Red")
        ),
      );
  }
}
class Green extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 400,
      height: 400,
      color: Colors.green,
      child: (
         Text("Red")
        ),
      );
  }
}
```