【Flutter】はじめてのFlutterでカウントアプリ作ってみた

# はじめに
この記事は「[HTC Advent Calendar 2020](https://qiita.com/advent-calendar/2020/htc)」の1日目の記事です。

執筆はHTCチームの開発担当のこーたです。
普段は、SI企業に勤め、インフラエンジニアとして働いています。
今回はチームメンバの技術向上のためにアドベントカレンダーにチームで参加してみることにしました。

いやHTCってなに？!って感じだと思うので、HTCについて簡単に触れておきますね。
「[ONE JAPAN HACKATHON 2020](https://sites.google.com/view/one-japan-hackathon/%E9%81%8E%E5%8E%BB%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88/6th?authuser=0)」というハッカソンに参加した際に結成されたチームです。
ハッカソンで作成した作品についてはチームメンバーが記事を書いてくれているので、興味がある方はこちらをご覧ください。

- [ONE JAPAN HACKATHONに参加した話](https://kurasher.hatenablog.com/entry/2020/09/05/215807)
 
- [やぎと不在票でリモートハッカソン優勝した話](https://note.com/9ninece/n/nd952f2d84b2f?fbclid=IwAR3uo-N7jMHYBcMb-hq-6aF3P7TvZgb_tKrbowbN4btqIkcIHXoIGQ-70rA)

本記事はタイトルにも記載している通り、はじめてFlutterをやってみたという内容です。
似たような記事が多くあり、新規性は皆無ですが、個人的なアウトプットと後学のために書かせて頂きます。

# 対象読者
- はじめてFlutterの開発を行う人
- Flutterの環境構築が完了している

# 実行環境
- macOS Catalina バージョン10.15.7
- Flutter バージョン1.20.4
- Dart バージョン2.9.2

# Flutterとは
Googleが提供しているUIツールキットです。モバイル・Webおよびデスクトップようにネイティブコンパイルされた、美しいアプリケーションを単一のコードベースから構築できると言われています。

# 今回作るもの
ボタンが２つあり、足し算と引き算ができるカウントアプリを作ります。
<img width="35%" alt="qiita_demo.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917920/3c7eae22-50a2-35da-e1ec-b467ecd380d4.gif">

# アプリの実装
まずは、新規Flutterプロジェクトの作成を行い、以下のような画面が表示されることを確認します。
![first_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917920/aecc93b3-be89-bcd2-4448-3546d89ec139.png)

## ボタンの追加
次にボタンの追加を行います。今回はRaisedButtonを使用します。
`.icon()`を使用することでアイコン付きのボタンになります。
`Icons.add_circle`でアイコンを選択することができます。[こちら](https://api.flutter.dev/flutter/material/Icons-class.html)からアイコン一覧を確認することができます。
`onPressed: _incrementCounter`：ボタンをタッチした際の処理を指定できます。

```dart:main.dart
// ... 略
class _MyHomePageState extends State<MyHomePage> {
// ... 略
  @override
  Widget build(BuildContext context) {
// ... 略
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton.icon(
                  icon: const Icon(
                    Icons.add_circle,
                    color: Colors.white,
                  ),
                  label: const Text('Plus'),
                  onPressed: _incrementCounter,
                  color: Colors.red,
                  textColor: Colors.white,
                ),
                SizedBox(width: 30),
                RaisedButton.icon(
                  icon: const Icon(
                    Icons.remove_circle,
                    color: Colors.white,
                  ),
                  label: const Text('minus'),
                  onPressed: _decrement,
                  color: Colors.blue,
                  textColor: Colors.white,
                ),
              ],
            ),
// ... 略
  }
}

```

ボタン追加後はこのような画面になっていると思います。
全てのパーツが中央に寄っていますが、とりあえずボタンの配置は完了です。
![add_button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917920/91dd8305-30bf-c9d5-fbb3-40257fa7336f.png)

## マイナス処理の追加
ボタンを押すたびに加算される処理は最初から実装されているので、ここでは減算処理を追加します。

```dart:main.dart
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  void _decrement() {
    setState(() {
      _counter--;
    });
  }
// ... 略
}
```

## レイアウトの変更
最後に簡単にレイアウトを整えます。方法はいくつかあるようですが、今回はSpacerとSizedBoxを使用しました。
`Spacer`は文字通りスペースをとるためのウィジェットです。`Row`や`Column`ウィジェットで`mainAxisAlignment`プロパティだけでは制御できないレイアウトを作るときによく利用されるようです。
`SizedBox`ウィジェットは、指定されたサイズの箱を作れます。プロパティは`width`、`height`、`child`だけとなっています。

```dart:main.dart
class _MyHomePageState extends State<MyHomePage> {

// ... 略

  @override
  Widget build(BuildContext context) {

// ... 略

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Spacer(
              flex: 2,
            ),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            Spacer(),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,

// ... 略

            ),
            Spacer(),
          ],
        ),
      ),
    );
  }
}

```

レイアウトを変更した結果が以下になります。簡単にボタンやテキスト間にスペースをとることができました。
(Flutter初心者過ぎて、このようなアプリ設計が正しいのかわからないので、どなたか詳しい方がいたら教えていただきたいです。）
![add_space.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917920/67af7601-9400-815f-c8c5-44be8aa10dc0.png)


# 参考文献
Flutter Doc JP 
https://flutter.ctrnost.com/basic/