FlutterのGoogle I/O Codelabを触ってみた。

# はじめに
私自身はAndroidエンジニアで、Android Nativeアプリの開発を今までやって来たけど、

- クロスプラットフォームアプリは開発したことがない。
- (Cordovaなら少々)
- Google I/Oの発表を聞いて「もしかしてFLutterの時代が来る？」と思った。
- 単純に興味がある。

と言った理由から今回Flutterを弄ってみることにした。
初めて触るので、こんな時に便利なのがGoogle I/OのCodelab。

今回は下記の3つを触ってみた。(所用時間としては2時間半程度でした。)

[Write Your First Flutter App, part 1](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1/index.html)
[Write Your First Flutter App, part 2](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/index.html)
[MDC-102 Flutter: Material Structure and Layout (Flutter)](https://codelabs.developers.google.com/codelabs/mdc-102-flutter/index.html)

なお、実施環境としては以下です。

開発PC:Mac Book
IDE:Android Studio 3.0.1

ここからはFlutterを触る前に自分で疑問に思ったことをQA形式で答える形で触った感想を書いていきたいと思います。

# Q1.どうやってクロスプラットフォームを実現している?
## A.io.flutter.app.FlutterActivityを継承したMainActivity上で動作するようになっている。

Flutter用のプロジェクトを作成するとAndroid と iOSのそれぞれの環境で動く中間コードが作られる。

<img width="371" alt="スクリーンショット 2018-05-22 22.46.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/115635/766b1232-8e4c-ef04-77dd-9d86efc1967e.png">

アプリ起動時に動作するActivityはあくまでMainActivityであり、MainActivityのonCleate時にGeneratedPluginRegistrant.registerWith(activity)を実施することで、後のUI制御はdart上で実装できるようになっている。

```sample.kt
import android.os.Bundle

import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity(): FlutterActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)
  }
}
///わざわざKotlinで書く意味はないと思う。
```

# Q2.Dartって何？
## A.Google が開発したプログラミング言語。文法的はJavaに似ている。

以下のように、import文が存在し、mainメソッドが開始の合図になり、クラス宣言や「extends」句など、Javaの影響を強く受けているように取れる。
型を厳密にしたかったのではないだろうか。

```sample.dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

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

class MyApp extends StatelessWidget {
```

# Q3.ぶっちゃけどうやって作るの？
## A.FlutterSDKが提供するWidgetをDartファイル上で組み合わせて作る。UI部分のレイアウトやどんな文字、アイコンを出すのかも全てDart上で実装する。

例えば以下のような簡単な画面もDart上で簡単に実装することが可能。

<img width="261" alt="スクリーンショット 2018-05-22 23.08.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/115635/a3ad106c-6f5a-65b9-4eb0-21fb35490c32.png">

コードはこんな感じ。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: const Text('Hello World'),
        ),
      ),
    );
  }
}
```

Flutterが提供するMaterialAppウィジェットにtitleやhome（それの子要素のappBarやbody）と言ったパラメータを与えるだけで、画面を実装することができる。
Flutterは[マテリアルデザイン](https://material.io/design/)に準拠しており、提供されるWidgetも普通に使えばマテリアルデザイン準拠になる。

レイアウトを細かくいじる時もWidgetが提供してくれるパラメータに設定することで調整が可能。

テキストボックスをつけたり、

```textbox.dart
TextField(
  decoration: InputDecoration(
    filled: true,
    labelText: 'Username',
  ),
),
```

ボタンを配置したり、

```button.dart
ButtonBar(
  children: <Widget>[
    FlatButton(
      child: Text('CANCEL'),
      onPressed: () {
      },
    ),
    RaisedButton(
      child: Text('NEXT'),
      onPressed: () {
      },
    ),
  ],
),
```

ウィジェットの間に、SizedBoxを入れたりして、余白を作ったりもできる。

```Sizedbox.dart
SizedBox(height: 120.0),
```

ウィジェットも豊富にあるので、マテリアルデザインに準拠したアプリを作るならばあまり苦労はしないのではと思う。
https://docs.flutter.io/flutter/widgets/widgets-library.html

# Q4.独自のウィジェットとか作れるの？
## A.わからないので、後日調査する。

# Q5.ネイティブの機能は使える？
## A.使える。（と思う。）

以下のページのやり方でネイティブ側のカメラを呼び出すことはできる様子。（ただ、試しにやってみたらエラーになったので、実装に問題があるので追加調査する。）
https://pub.dartlang.org/packages/camera

# Q6.マテリアルデザインに準拠しない独自デザインのアプリは作れる？
## A.頑張れば作れるかもしれないけど、向いていないと思う。
MaterialAppと言ったFlutterが提供するウィジェットがマテリアルデザイン準拠なので、言い換えれば、ある程度はマテリアルデザインであることを強制されるはず。
独自デザインでやりたければ、Flutter以外のクロスプラットフォームか、ネイティブで実装した方がいい。

# Q7.Flutterがネイティブアプリの標準になる？GoogleはFlutterを勧めて、PWA,ネイティブアプリは過去のものになる？
## A. 向き不向きがあるので、上手にすみ分けが進むと思う。


# おわりに
まだちょっと触り始めたばかりなので、簡単な感じで終わりましたが、まだ実施していないCodelabはあるし、まだまだ疑問に思うことはたくさんあるので、調べたり、場合によっては中のコードを覗いてみたりして、理解を深めていきたいと思います。
Thank you for reading this to the end.